Skip to content

fix(auth): default to classic token guidance and warn about fine-grained limits (#594) - #604

Merged
AmintaCCCP merged 1 commit into
mainfrom
fix/token-guidance-classic-default-594
Nov 12, 2026
Merged

AmintaCCCP merged 1 commit into
mainfrom
fix/token-guidance-classic-default-594

Conversation

@AmintaCCCP

@AmintaCCCP AmintaCCCP commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

Description

Resolves #594.

Background

When users use GitHub Fine-grained Personal Access Tokens (PATs) to manage stars:

  1. GitHub restricts Fine-grained PATs to the designated Resource Owner. Calling DELETE /user/starred/{owner}/{repo} or PUT /user/starred/{owner}/{repo} on repositories belonging to other users or organizations often results in 403 Forbidden (Resource not accessible by personal access token) or 404 Not Found if scoped via "Only select repositories" or blocked by organization PAT policies.
  2. Fine-grained PATs do not support GitHub Lists (starred lists) API due to lack of user scope support.
  3. Previously, the token permissions dialog defaulted to the "Fine-grained" tab without explaining these restrictions, causing users to mistakenly assume Fine-grained PATs are recommended and fully supported for all star management operations.

Changes

  1. Default to Classic Token: In GitHubTokenPermissions.tsx, set the default active mode to 'classic' and ordered the "Classic Token" tab first.
  2. Pre-fill Scopes for Classic Token Creation: Updated the GitHub token creation link for classic mode to prefill the required scopes (public_repo,gist,user):
    https://github.com/settings/tokens/new?description=GithubStarsManager&scopes=public_repo,gist,user
    This lets users generate a correctly scoped token with a single click.
  3. Fine-grained Limitations Callout: When users switch to the "Fine-grained Token" tab, displayed a clear warning callout highlighting:
    • Inability to reliably star/unstar repositories across organizations or third parties (403 errors).
    • Inability to sync Star Lists (GitHub API limitation).
    • Recommendation to switch to Classic Token with a one-click button.
  4. Localization & Parity: Added translations across all 10 supported languages (zh, zh-TW, en, ja, ko, de, es, fr, pt-BR, ru).
  5. Tests: Updated src/components/LoginScreen.test.tsx to verify default tab selection, limitation callouts, tab switching, and dynamic creation URLs.

Verification

  • npm run check:i18n (passed)
  • npm run typecheck (passed)
  • npm run lint (passed)
  • npm test -- --run (all 195 test files, 2416 tests passed)

Summary by CodeRabbit

  • 新功能
    • 登录时默认选择经典 GitHub Token,并根据所选类型提供对应的创建链接。
    • 细粒度 Token 面板现会说明其在管理组织或他人仓库星标、同步 Star 列表方面的限制,并提供切换到经典 Token 的入口。
    • 新增相关限制说明的多语言文案。
  • 测试
    • 补充对默认选项、权限提示、限制说明及创建链接切换行为的验证。

@chatgpt-codex-connector

Copy link
Copy Markdown
Codex Review Summary: ❌ Failed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ❌ Failed 2026-11-12T12:37:22.174866Z
We couldn’t complete this review. Comment @codex review to try again.
f3c82f1 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ghfind-review ghfind-review Bot added the review: high ghfind author score; see https://ghfind.com label Nov 12, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

登录界面的 Token 权限面板默认选择 classic Token,并按模式显示对应的 GitHub 创建链接。fine-grained 面板新增限制警告和切换到 classic 的操作。测试和九种语言的登录文案同步更新。

Changes: GitHub Token 登录指引

Layer / File(s) Summary
Token 模式与创建链接
src/components/GitHubTokenPermissions.tsx, src/components/LoginScreen.test.tsx
classic Token 成为默认选项并排在 fine-grained Token 之前。创建链接随模式切换。测试验证默认权限和两种创建链接。
Fine-grained 限制提示与本地化
src/components/GitHubTokenPermissions.tsx, src/components/LoginScreen.test.tsx, src/locales/*/login.json
fine-grained 面板新增 Star 操作和 Star 列表同步限制提示,并提供切换到 classic Token 的操作。测试及九种语言文案覆盖这些提示。

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: khk-nl

Merge Risk: Minimal · up to f3c82

This changes the token guidance in the login dialog to recommend classic tokens by default and warns about fine-grained limits. No concrete merge-blocking issue was found, so the risk is minimal.

Pre-merge checks: Passed 4

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed 标题描述了主要变更:将默认 token 指引改为经典 Token,并增加细粒度 Token 限制警告。摘要中的文件变更(GitHubTokenPermissions.tsx、LoginScreen 测试和十种语言的 login.json)均与该标题一致。标题未列出文件,且包含 PR 编号 (#594),但这不影响其与变更内容的相关性。
Linked Issues check Passed 关联 Issue:[#594]。该 Issue 是用户提问,描述“Token 已添加权限,取消 Star 仍提示无权限”。Issue 未提供明确验收标准。PR 的目标是处理该问题的可能原因:Fine-grained PAT 对他人或组织仓库的 Star 操作受限,且不支持 Star Lists。实现内容如下。(1) `src/components/GitHubTokenPermissions.ts…
Out of Scope Changes check Passed PR 中的变更均与 [#594] 的权限引导问题相关。GitHubTokenPermissions.tsx 的默认模式、标签顺序、链接和警告属于核心变更。LoginScreen.test.tsx 中的测试用于验证这些变更。十种语言的 login.json 文案用于保持本地化一致,并通过 npm run check:i18n 检查。未发现与 Issue 无关的功能或重构。摘要中未出现…
Full details: Linked Issues check

Explanation

关联 Issue:[#594]。该 Issue 是用户提问,描述“Token 已添加权限,取消 Star 仍提示无权限”。Issue 未提供明确验收标准。PR 的目标是处理该问题的可能原因:Fine-grained PAT 对他人或组织仓库的 Star 操作受限,且不支持 Star Lists。实现内容如下。(1) src/components/GitHubTokenPermissions.tsx 将默认模式设为 classic,并将 Classic 标签置于首位。(2) Classic 创建链接预填 public_repo,gist,user scopes。(3) Fine-grained 面板新增限制警告,并提供切换到 Classic 的操作。(4) src/components/LoginScreen.test.tsx 覆盖默认标签、警告显示、标签切换和链接 URL。(5) 十种语言的 login.json 同步新增文案。以上内容覆盖了 Issue 所涉及的操作路径。PR 描述和摘要中的证据支持该判断。未检查仓库源码差异。

Full details: Out of Scope Changes check

Explanation

PR 中的变更均与 [#594] 的权限引导问题相关。GitHubTokenPermissions.tsx 的默认模式、标签顺序、链接和警告属于核心变更。LoginScreen.test.tsx 中的测试用于验证这些变更。十种语言的 login.json 文案用于保持本地化一致,并通过 npm run check:i18n 检查。未发现与 Issue 无关的功能或重构。摘要中未出现无关文件。未检查仓库源码差异,因此结论基于摘要证据。

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d37c17bd-d6a0-4dc4-b9fb-290087227a4d
Commits

Reviewing files that changed from the base of the PR and between 32f877f and f3c82f1.

Files selected for processing: 12

  • src/components/GitHubTokenPermissions.tsx
  • src/components/LoginScreen.test.tsx
  • src/locales/de/login.json
  • src/locales/en/login.json
  • src/locales/es/login.json
  • src/locales/fr/login.json
  • src/locales/ja/login.json
  • src/locales/ko/login.json
  • src/locales/pt-BR/login.json
  • src/locales/ru/login.json
  • src/locales/zh-TW/login.json
  • src/locales/zh/login.json

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.

@github-actions

Copy link
Copy Markdown
Contributor

📸 UI 预览

f3c82f1 的界面截图,由 ui-preview 工作流 自动生成(内置演示数据,无真实凭据):

登录页

登录页

设置 · 通用

设置 · 通用

截图托管于 ui-previews 分支;
PR 中新的 UI 提交会自动刷新本评论。

github-actions Bot added a commit that referenced this pull request Nov 12, 2026
@AmintaCCCP
AmintaCCCP merged commit 6b895ac into main Nov 12, 2026
32 checks passed
AmintaCCCP added a commit that referenced this pull request Nov 12, 2026
- CodeQL js/incomplete-sanitization: the sources-dialog has-text selector
  escaped only quotes; a locale title containing a backslash could escape
  the escape character and break the selector string. Escape backslashes
  and quotes together.
- isDesktopBridgeOnlyDiff (CodeRabbit majors): the multiset line diff
  judged pure reorders as no-change, and any line merely mentioning
  desktopBridge/electronProxy counted as web-inert — a bridge ternary with
  changed web fallback values or swapped assignments would slip through as
  ui=false. The diff now separates additions from removals, treats a
  multiset-empty diff between different contents (a reorder) as
  non-inert, and only accepts lines shaped like bridge imports, bridge
  call statements, the isSupported() guard, or bare syntax; anything that
  assigns from the bridge or branches on it for web values stays
  non-inert.

Verified: the #603 head/base replay still yields ui=false (its diff is
purely additive bridge-shaped lines); #604 replay unchanged; node test
suite passes with new reorder/ternary regression cases.
AmintaCCCP added a commit that referenced this pull request Nov 12, 2026
Third CodeRabbit round on isDesktopBridgeOnlyDiff — the line-shape
whitelist still had three holes, all rooted in the same limitation: a
multiset diff plus per-line shapes cannot see what the unchanged lines
around a change mean. Replaced with a stronger formulation:

- webProjection: the in-order sequence of non-bridge lines must be
  byte-identical in both versions. This catches pure web reorders the
  multiset cannot see, including reorders mixed with additive bridge
  calls (the line-level reorder blind spot).
- guard-block analysis: every ADDED if (desktopBridge.isSupported())
  block (head) and every REMOVED one (base) must contain only
  bridge-shaped or bare-syntax lines. Wrapping or unwrapping an
  unchanged web statement makes its execution conditional on the desktop
  bridge — web-visible, previously invisible to line shapes.
- bridge call arguments are restricted to side-effect-free expressions
  (no nested calls, assignments or braces), so an argument cannot smuggle
  web-relevant side effects past the check.

Multiset equality between different contents (pure reorder) now falls
out of the projection comparison; byte-identical files stay inert;
anything unreadable or ambiguous stays non-inert (conservative: more
screenshots, never fewer). The #603 head/base replay still yields
ui=false; #604 unchanged; experiment baseline unchanged; new regression
tests cover guard wrap/unwrap, reorder+bridge mixes, and argument side
effects.
AmintaCCCP added a commit that referenced this pull request Nov 12, 2026
Fourth CodeRabbit round: moving an existing guard's closing brace to
absorb (or release) an unchanged web statement left the guard count and
the web line multiset untouched, so the diff passed as web-inert while
the statement's execution became conditional in the browser.

Replaced the occurrence-flag machinery with a single recursive web
projection: bridge-shaped and bare-syntax lines are omitted; a
desktopBridge.isSupported() guard block is transparent only when its own
projection is empty, otherwise it is emitted as a guard{...} token.
Web-inertness now means the base and head projections are identical,
which uniformly covers wrapping, unwrapping, boundary moves, web
reorders, and content edits; pre-existing guards that stay untouched
compare equal on both sides. Unbalanced braces degrade conservatively
(the remaining range is emitted raw).

#603/#604 replays unchanged; experiment baseline unchanged; new
regression tests cover both brace-move directions and the untouched
pre-existing guard.
AmintaCCCP added a commit that referenced this pull request Nov 12, 2026
Fifth CodeRabbit round: the guard-boundary scan counted braces per raw
character, so a } inside a comment or a string literal could close a
guard block on the scanner's behalf. Two versions whose guard wrapped
different statements could then compare equal and pass as web-inert.

Added braceDeltasPerLine: a single-pass scanner that skips line/block
comments and string/template literals (state carries across lines;
unterminated constructs at EOF return null and fail conservatively), and
projectRange now derives guard boundaries from those deltas. Comment-only
lines join the structural class (they cannot render). Known heuristic
edge: regex literals with unpaired braces/quotes may shift the scan and
degrade conservatively.

Verified: the CodeRabbit comment example and a string-brace variant are
non-inert; the #603 head/base replay still yields ui=false; #604 and the
experiment baseline are unchanged; the full test suite passes.
AmintaCCCP added a commit that referenced this pull request Nov 12, 2026
Sixth CodeRabbit round: a /}/ inside a regex literal (e.g.
void /[}]/.test(language)) was still counted as a code brace, so a guard
boundary could close on it and two differently-wrapped versions could
compare web-equal. The scanner now recognizes regex literals with the
standard previous-token heuristic (operator/opening bracket/keyword
before the slash, character-class tracking inside) and skips their
contents; misjudging a division as a regex is the direction that keeps
braces counted, so any residual imbalance degrades conservatively.

Both brace-move directions around a regex-bearing guard are covered by
new regression tests; #603/#604 replays and the experiment baseline are
unchanged.
AmintaCCCP added a commit that referenced this pull request Nov 12, 2026
Eighth CodeRabbit round: the operator whitelist included + - * % ~ ^, so
a slash after counter++ (division) was scanned as a regex start and its
closing slash swallowed the guard's closing brace, making two
differently-wrapped versions compare web-equal.

The whitelist now contains only token boundaries where a regex is the
only valid continuation (( [ { , ; = : ! & | ? > and the regex-allowing
keywords); every other slash is flagged ambiguous and the file stays
non-inert. There is no guessing path left: a slash either provably opens
a regex or the whole diff keeps its scene classification. Regression
tests cover both brace-move directions around counter++ / 2; the #603
replay, #604 and the experiment baseline are unchanged.
AmintaCCCP added a commit that referenced this pull request Nov 12, 2026
The incremental backward heuristics kept leaking: a line comment's body
could masquerade as a token in tokenBefore (whitespace skipping crossed
into comment text), and the newline handling left the scanner stuck in
the line-comment state after the first //, poisoning the whole file.
Both surfaced as the #603 replay regressing to ui=true.

Replaced the pair of scanners with one forward pass (analyzeCode) that
produces a per-character code mask (comments, strings, template literals
and regex contents are unmasked; the ambiguous-slash flag and an
unterminated construct at EOF mark the file unanalyzable), the per-line
brace deltas, and the mask. tokenBefore is now a mask-based backward
skip, so comment bodies can never masquerade as tokens regardless of
formatting. Verified: the CodeRabbit comment example, a string-brace
variant, and a template absorb all stay non-inert; additive bridge
diffs stay inert; the #603 head/base replay is ui=false again; #604 and
the experiment baseline are unchanged; the full suite passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: high ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Token 已经添加相应权限,取消 Star 还是提示无权限

1 participant