Skip to content

fix: restore account and profile pages and enforce Chinese UI - #1040

Merged
boomzero merged 34 commits into
devfrom
codex/fix-account-page-migration
Oct 4, 2026
Merged

boomzero merged 34 commits into
devfrom
codex/fix-account-page-migration

Conversation

@boomzero

@boomzero boomzero commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

What does this PR aim to accomplish?:

Fix account navigation and userscript features after XMOJ migrated account editing from /modifypage.php to /modify_user_info.php. Restore missing profile sections when optional requests fail or stall, and replace the broken native submission-history renderer. Remove language selectors and enforce Chinese across the classic and /web UIs.

Closes #920.
Closes #618.

How does this PR accomplish the above?:

  • Point account navigation and the changelog at /modify_user_info.php. Redirect defunct /modifypage.php links to the current endpoint, preserving their query and fragment; remove the obsolete account/password form replacement and POST handler.
  • Initialize a visible “标签编辑” panel on the current account page before the general page handler. It does not depend on the old navbar, wrapper layout, or the presence of a <form> and is separate from native account controls. Preserve native fields, CSRF data, and submit listeners; keep AC-code export available.
  • Disable badge fields until their existing values load, use defaults for incomplete data, and provide retry controls on load failures. Bound badge requests and recover from network, timeout, abort, HTTP, and malformed-response failures. Save badges independently and invalidate only this user's badge cache.
  • Render the complete profile synchronously before optional badge and last-online requests. Restore avatar, username, nickname, rating, message link, admin badge actions, and solved problems with their submission counts. Derive avatar and rating from native profile data, retain native statistics nodes and handlers, provide badge retry controls, and replace the overlapping chart legend with a flowing layout. Parse solved-problem links and numeric calls without evaluating native scripts, including for standard uploads.
  • Fix [Bug] userinfo.php 图表被移除 #618 by reading the native numeric daily history statements without executing their JavaScript and drawing both series on one SVG graph with a shared date/count scale. Paint translucent accepted bars beneath a thin, translucent submission line; remove visible per-day dot markers so dense history stays readable while keeping hover targets and Chinese tooltips. Keep the graph visible with the default cleanup setting, add Chinese date/count tooltips, resize the axes and date labels for narrow layouts, and inherit light/dark theme colors. Show a clear message for empty or unavailable history; no jQuery, Flot, added library, or extra history request is needed.
  • Set the /web language cookie at document-start and hide navigation, statement, and native account-form language selectors. Select the Chinese account radio and preserve that value on native submit and FormData serialization without disabling its inputs or disturbing other account fields. Persist the classic preference when the current account form is saved; remove calls to the broken /change_lang.php endpoint and the resulting classic-page reloads. Keep Chinese statements selected after Vue navigation, and prevent /web reload loops with a retry message if its cookie preference is refused.
  • Recover the remaining stash@{0} request safeguards: ordinary API requests time out after 30 seconds and report transport failures once; requests with recovery callbacks retain their 15-second limit. The stashes’ contest compatibility, Markdown/TeX copying, and ended-contest fallback are already included through prior merges. Preserve both stash entries and retain the current implementations when resolving their older code. Update the compatibility documentation to reflect Chinese-only UI.
  • Add offline Chromium regressions for native account fields and listeners, varied account layouts and pages without a form, visible badge loading and saving, incomplete data, pending loads, load/save errors and retries, cache invalidation, defunct-route redirects, navigation, changelog rendering, Chinese language enforcement, and profile restoration during pending and failed requests. Cover profile identity, native links and handlers, missing fields, admin badge actions, standard-upload parsing, and the chart under the monochrome skin. Require the Chinese startup call to exist before asserting initialization order.

Validation: all 90 tests pass using the installed Chromium via XMOJ_CHROMIUM. node --check XMOJ.user.js and git diff --check pass. Use the actual relative-time formatter in profile tests and verify readable last-online text plus the native date tooltip. Exercise the actual document-start redirect and verify classic pages never call the broken language endpoint or reload. Cover wrapped and direct account radio groups, numeric language values, preservation of nickname/CSRF fields and submit handlers, and Chinese serialization after English is reselected programmatically. Visually checked the profile layout using the configured Bootstrap stylesheet and monochrome skin. For the replacement graph, rendered 290 submission records and 224 accepted records from the live profile in light, dark, and mobile layouts; tested rendering with Flot absent, both cleanup settings, safe parsing, sorting/deduplication, data/tooltips, narrow axes, and empty/unavailable history. Verify that both series share one graph and baseline, matching dates align, accepted bars paint behind the thin submission line, both layers use transparency, and dense submission markers remain invisible. Verify that a lone history point is visible and single-date histories render only one centered date label.

Live authenticated account editing was not tested. The final checklist remains unchecked because template item 11 requires human verification with the installed userscript.


By submitting this pull request, I confirm the following:

  1. I have read and understood the contributor's guide, as well as this entire template. I understand which branch to base my commits and Pull Requests against.
  2. I have commented on my proposed changes within the code.
  3. I have tested my changes.
  4. I am willing to help maintain this change if there are issues with it later.
  5. It is compatible with the GNU General Public License v3.0
  6. I have squashed any insignificant commits. (git rebase)
  7. I have checked that another pull request for this purpose does not exist.
  8. I have considered and confirmed that this submission will be valuable to others.
  9. I accept that this submission may not be used, and the pull request can be closed at the will of the maintainer.
  10. I give this submission freely and claim no ownership to its content.
  11. I have verified that my changes work correctly in both the new UI and the old/classic UI.

  • I have read the above and my PR is ready for review. Check this box to confirm

Summary by Sourcery

Restore userscript account features across XMOJ’s migrated and legacy settings pages.

New Features:

  • Support the migrated account settings page while retaining legacy account editing, badge management, and AC-code export capabilities.

Bug Fixes:

  • Restore account and changelog navigation after XMOJ moved account editing to the migrated route.
  • Prevent account and password page customization from disrupting native forms, CSRF data, or site-installed event handlers.
  • Make badge loading and saving resilient to incomplete data and request failures while ensuring controls recover for retries.

Enhancements:

  • Share account badge handling across migrated and legacy settings pages and scope badge cache invalidation to the current user.
  • Preserve changelog rendering and login or error messages across account-related routes.

Build:

  • Bump the userscript and package version to 3.8.3 and include the release update metadata.

Tests:

  • Add offline Chromium regression coverage for migrated and legacy account pages, native form preservation, badge failures and retries, navigation, changelog rendering, and related account states.

Summary by cubic

Restores XMOJ account and profile pages after account editing moved to /modify_user_info.php, replaces the broken native submission-history renderer, and enforces Chinese across the classic and /web UIs. Closes #920 and #618, and bumps the userscript and package to 3.8.3.

Bug Fixes

  • Account, changelog, and settings-welcome links point to the migrated endpoint; defunct /modifypage.php links redirect with query and fragment preserved, and legacy account editing stays available.
  • The migrated page keeps its native form, fields, CSRF token, and submit handler; badges are saved separately and AC-code export remains available.
  • Badge loading and saving handle missing or invalid data and recover from network, timeout, abort, HTTP, and malformed-response failures without leaving the save button disabled.
  • Profile identity, rating, tags, last-online, and solved-problem info render before optional requests, so failures no longer leave sections blank; last-online shows readable text and the chart legend overlap is fixed.
  • The submission-history graph is redrawn as SVG from native numeric statements, with submissions and accepted counts in separate aligned panels sharing the same date and count scales; per-day dot markers are removed so dense history forms no blob. No jQuery, Flot, added library, or extra request; handles empty history, narrow layouts, and light/dark themes with a theme-aware border and padding, and stays visible under the default cleanup setting.
  • The changelog renders on the migrated route and login/error messages stay intact; the separate password page is retained.
  • Language selectors are hidden, the /web cookie is set at document-start, classic English sessions are switched via the native endpoint, and reload loops are prevented.
  • Ordinary API requests time out after 30 seconds and report transport failures once; requests with recovery callbacks keep their 15-second limit.
  • Adds offline Chromium regressions covering form preservation, badge saves, profile restoration, history rendering, cache invalidation, navigation, changelog rendering, and Chinese enforcement.

Verification note: Live authenticated editing wasn't tested; please verify with the installed userscript in both the new and classic XMOJ UIs before merging.

Written for commit 4593892. Summary will update on new commits.

Review in cubic

@sourcery-ai

sourcery-ai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Updates account navigation and userscript processing for XMOJ’s migration to /modify_user_info.php without taking over the site’s native form, while retaining legacy behavior and adding offline Chromium coverage for the affected routes and features.

Sequence diagram for migrated account settings processing

sequenceDiagram
    participant User
    participant Page as AccountPage
    participant Script as XMOJScript
    participant API as BadgeAPI
    participant Storage as LocalStorage

    User->>Page: Visit /modify_user_info.php
    Script->>Page: IsAccountSettingsPage(pathname)
    alt ByUserScript parameter present
        Script->>Page: Render changelog
    else Normal account visit
        Script->>API: RequestAPI(GetBadge)
        API-->>Script: Badge data
        Script->>Page: InitializeAccountBadgeEditor(container)
        User->>Script: Click badge submit button
        Script->>API: RequestAPI(EditBadge)
        API-->>Script: Success or error result
        alt Success
            Script->>Storage: Remove cached UserScript-User badge keys
        end
    end
    Page-->>User: Preserve native account form and messages
Loading

Flow diagram for account route compatibility

flowchart TD
    Menu[Account and changelog navigation] --> Migrated["/modify_user_info.php"]
    Legacy["/modifypage.php"] --> Detect[IsAccountSettingsPage]
    Migrated --> Detect
    Detect -->|ByUserScript| Changelog[Render update changelog]
    Detect -->|Normal visit| Native[Keep site native form and CSRF fields]
    Native --> Badge[Add separate badge editor on migrated route]
    Native --> Export[Keep AC code export available]
    Detect -->|Missing structure or login/error page| Preserve[Preserve site messages]
Loading

File-Level Changes

Change Details Files
Route account-related navigation and page handling through the migrated settings endpoint while preserving legacy compatibility.
  • Added a shared account-settings route predicate for both endpoints.
  • Updated account, changelog, and welcome links to target /modify_user_info.php.
  • Rendered the changelog on both routes and bypassed account enhancements for login/error pages.
  • Kept the password page and legacy account enhancement behavior unchanged.
XMOJ.user.js
Separate userscript features from the migrated site's native account form.
  • Added an API-backed badge editor appended outside the native form.
  • Preserved native fields, CSRF data, submit handling, and migrated form structure.
  • Cleared only the current user's badge cache after successful saves and retained AC-code export on normal account pages.
XMOJ.user.js
Add Chromium regression coverage for migrated and legacy account flows.
  • Added tests for native form preservation, badge success/failure and cache invalidation, changelog and navigation behavior, login/error handling, legacy enhancement, password-page isolation, and AC-code export.
  • Included the new test file in the npm test command.
tests/account-settings.test.cjs
package.json

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@hendragon-bot hendragon-bot Bot added the user-script This issue or pull request is related to the main user script label Oct 3, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Deploying xmoj-script-dev-channel with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4593892
Status: ✅  Deploy successful!
Preview URL: https://27aaaaec.xmoj-script-dev-channel.pages.dev
Branch Preview URL: https://codex-fix-account-page-migra.xmoj-script-dev-channel.pages.dev

View logs

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Fixed security issues:

  • Cross-site scripting (XSS) via untrusted HTML/JS injection in web rendering sinks (link)
Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="XMOJ.user.js" line_range="2178-2183" />
<code_context>
+        button.addEventListener("click", () => {
+            button.disabled = true;
+            status.innerText = "";
+            RequestAPI("EditBadge", {
+                "UserID": String(CurrentUsername),
+                "Content": content.value,
+                "BackgroundColor": background.value,
+                "Color": color.value
+            }, (result) => {
+                button.disabled = false;
+                status.innerText = result.Success ? "修改成功" : result.Message;
</code_context>
<issue_to_address>
**issue (bug_risk):** When the EditBadge request fails at the transport layer or returns invalid JSON, `RequestAPI` does not invoke the callback, so the badge button remains disabled permanently and the user receives no failure status.

**Triggers:** When saving a badge encounters a network error or malformed API response.

**Suggested fix:** Add an error callback or make `RequestAPI` reject/notify callers on transport and parsing failures, then re-enable the button and display an error message.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 1 finding to address first, and a faulty badge editor could persist an incorrect badge value or colors through the EditBadge API, and reverting the script would not undo that server-side change. The value is bounded and can be corrected by editing the badge again; the native account form and its CSRF fields are preserved.

Blocking findings: XMOJ.user.js:2183


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread XMOJ.user.js Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 67dccb0e83

ℹ️ 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".

Comment thread XMOJ.user.js Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread XMOJ.user.js Outdated
Comment thread tests/account-settings.test.cjs
Comment thread XMOJ.user.js Outdated
Comment thread XMOJ.user.js Outdated
Comment thread XMOJ.user.js

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files

Requires human review: Auto-approval blocked because this review re-detected 3 unresolved issues already reported by Cubic.

Re-trigger cubic

@pull-request-size pull-request-size Bot added size/XL and removed size/L labels Oct 4, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New security issues found

Comment thread XMOJ.user.js
Comment thread XMOJ.user.js
Comment thread XMOJ.user.js
Comment thread XMOJ.user.js
Comment thread XMOJ.user.js
Comment thread XMOJ.user.js
Comment thread XMOJ.user.js
Comment thread XMOJ.user.js

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread XMOJ.user.js Outdated
@PythonSmall-Q

Copy link
Copy Markdown
Member

我感觉看上去不错

@boomzero boomzero changed the title fix: support migrated account settings page fix: restore account settings and enforce Chinese UI Oct 4, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread tests/account-settings.test.cjs Outdated
@boomzero boomzero changed the title fix: restore account settings and enforce Chinese UI fix: restore account and profile pages and enforce Chinese UI Oct 4, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread XMOJ.user.js Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread XMOJ.user.js Outdated
@github-actions
github-actions Bot force-pushed the codex/fix-account-page-migration branch from 5b82e34 to 6737a97 Compare October 4, 2026 07:33

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread XMOJ.user.js Outdated
@github-actions
github-actions Bot force-pushed the codex/fix-account-page-migration branch from 2f21606 to f5eaedb Compare October 4, 2026 09:32

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="XMOJ.user.js">

<violation number="1" location="XMOJ.user.js:2448">
P3: These transparent circles still receive SVG pointer events, so on dense timelines they intercept short accepted bars and hide their `<title>` tooltips. Use a shared tooltip or non-overlapping hit targets so both counts remain discoverable.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread XMOJ.user.js
const submitted = Node("g", {"data-layer": "submitted"});
if (data[0].length) Node("path", {d: data[0].map(([timestamp, count], index) => (index ? "L" : "M") + X(timestamp) + " " + Y(count)).join(" "), fill: "none", stroke: colors[0], "stroke-width": "1.25", "stroke-opacity": "0.8", "data-series": "submitted"}, null, submitted);
for (const [timestamp, count] of data[0]) {
const point = Node("circle", {cx: X(timestamp), cy: Y(count), r: data[0].length === 1 ? "3" : "5", fill: data[0].length === 1 ? colors[0] : "transparent", "data-series": "submitted"}, null, submitted);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: These transparent circles still receive SVG pointer events, so on dense timelines they intercept short accepted bars and hide their <title> tooltips. Use a shared tooltip or non-overlapping hit targets so both counts remain discoverable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At XMOJ.user.js, line 2448:

<comment>These transparent circles still receive SVG pointer events, so on dense timelines they intercept short accepted bars and hide their `<title>` tooltips. Use a shared tooltip or non-overlapping hit targets so both counts remain discoverable.</comment>

<file context>
@@ -2424,32 +2425,34 @@ function InitializeProfileActivityChart(chart) {
+        const submitted = Node("g", {"data-layer": "submitted"});
+        if (data[0].length) Node("path", {d: data[0].map(([timestamp, count], index) => (index ? "L" : "M") + X(timestamp) + " " + Y(count)).join(" "), fill: "none", stroke: colors[0], "stroke-width": "1.25", "stroke-opacity": "0.8", "data-series": "submitted"}, null, submitted);
+        for (const [timestamp, count] of data[0]) {
+            const point = Node("circle", {cx: X(timestamp), cy: Y(count), r: data[0].length === 1 ? "3" : "5", fill: data[0].length === 1 ? colors[0] : "transparent", "data-series": "submitted"}, null, submitted);
+            Node("title", {}, DateLabel(timestamp) + " 提交:" + count, point);
+        }
</file context>

@boomzero
boomzero merged commit e816557 into dev Oct 4, 2026
7 checks passed
@boomzero
boomzero deleted the codex/fix-account-page-migration branch October 4, 2026 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XXL user-script This issue or pull request is related to the main user script

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants