mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-31 11:01:36 +08:00
fix(deeplink): import usage scripts disabled and show their code
An imported usage script is JavaScript that runs whenever usage is
queried. Two things made it possible to acquire one without seeing it:
- `usage_enabled.unwrap_or(!code.is_empty())` treated the presence of
code as a decision to run it, so a link that simply carried a script
got it enabled
- the confirmation dialog rendered only an enabled/disabled badge; the
script body was never displayed
Default to disabled. Enabling now requires `usageEnabled=true` in the
link -- which is the link author's request, not the user's consent. The
consent is the user pressing Import after seeing the full script body
and the badge, which is why both displays are load-bearing rather than
decorative.
The badge predicate moves from `!== false` to `=== true` to match the
new backend default. Left alone it would have started rendering "did not
say" as a green "Enabled" -- more optimistic than what would actually
happen.
Extracts the payload decode into `decodeDeeplinkPayload`, which falls
back to the raw string when decoding fails or yields empty. A dialog
whose job is to show what is about to be written must not let a payload
vanish just because it is malformed; empty reads as "there is no
script", which is exactly the wrong impression.
This commit is contained in:
@@ -20,9 +20,11 @@ import { ProviderIcon } from "./ProviderIcon";
|
||||
import {
|
||||
classifyEndpoint,
|
||||
classifyEnvKey,
|
||||
decodeDeeplinkPayload,
|
||||
maskValue,
|
||||
riskI18nKey,
|
||||
} from "@/utils/deeplinkRisk";
|
||||
import { decodeBase64Utf8 } from "@/lib/utils/base64";
|
||||
|
||||
interface DeeplinkError {
|
||||
url: string;
|
||||
@@ -649,14 +651,19 @@ export function DeepLinkImportDialog() {
|
||||
})}
|
||||
</div>
|
||||
<div className="col-span-2 text-sm">
|
||||
{/*
|
||||
判据是 `=== true`,与后端 `usage_enabled.unwrap_or(false)`
|
||||
严格对齐。此前用的 `!== false` 会把"链接没说"渲染成绿色的
|
||||
「已启用」——徽章必须显示实际会发生的事,不能比后端更乐观。
|
||||
*/}
|
||||
<span
|
||||
className={`inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium ${
|
||||
request.usageEnabled !== false
|
||||
request.usageEnabled === true
|
||||
? "bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-300"
|
||||
: "bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400"
|
||||
}`}
|
||||
>
|
||||
{request.usageEnabled !== false
|
||||
{request.usageEnabled === true
|
||||
? t("deeplink.usageScriptEnabled", {
|
||||
defaultValue: "已启用",
|
||||
})
|
||||
@@ -667,6 +674,33 @@ export function DeepLinkImportDialog() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/*
|
||||
脚本正文必须完整展示。这段是会执行的 JavaScript,而 payload
|
||||
常常整条藏在中间——`whitespace-pre-wrap break-all` + 可滚动容器,
|
||||
不用 truncate,任何字符都不得被 CSS 藏起来。
|
||||
*/}
|
||||
<div className="space-y-1">
|
||||
<div className="font-medium text-sm text-muted-foreground">
|
||||
{t("deeplink.usageScriptCode")}
|
||||
</div>
|
||||
<pre className="max-h-48 overflow-auto rounded border border-border-default bg-muted/40 p-2 text-xs font-mono whitespace-pre-wrap break-all">
|
||||
{decodeDeeplinkPayload(
|
||||
request.usageScript,
|
||||
decodeBase64Utf8,
|
||||
)}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
{/*
|
||||
无条件显示,不看 `usageEnabled`:代码无论启用与否都会被写入供应商
|
||||
配置,用户之后在应用内一键即可开启。挂条件等于让攻击者省略参数就能
|
||||
关掉这条警告。
|
||||
*/}
|
||||
<div className="text-yellow-600 dark:text-yellow-500 text-sm flex items-start gap-2">
|
||||
<span aria-hidden="true">⚠️</span>
|
||||
<span>{t("deeplink.usageScriptWarning")}</span>
|
||||
</div>
|
||||
|
||||
{/* Usage API Key (if different from provider) */}
|
||||
{request.usageApiKey &&
|
||||
request.usageApiKey !== request.apiKey && (
|
||||
|
||||
Reference in New Issue
Block a user