Skip to content

添加FRP功能#557

Closed
Socialism-tech wants to merge 6 commits intoSeaLantern-Studio:devfrom
Socialism-tech:dev
Closed

添加FRP功能#557
Socialism-tech wants to merge 6 commits intoSeaLantern-Studio:devfrom
Socialism-tech:dev

Conversation

@Socialism-tech
Copy link

@Socialism-tech Socialism-tech commented Mar 1, 2026

提交前检查清单

  • 已阅读 提交前测试必读!!!.md 并完成要求测试
  • 本地/CI 测试通过
  • 代码审查 (Self-review) 完成

变更分类(必选其一)

  • feat 新功能
  • fix Bug 修复
  • docs 文档/模板
  • style 代码格式(不影响功能)
  • refactor 重构(既不修复 bug 也不添加功能)
  • perf 性能优化
  • test 测试相关
  • chore 构建/CI/依赖/工具链
  • revert 回滚
  • security 安全修复

影响范围(可多选)

  • 前端 Frontend

    • UI 样式/布局
    • 组件/状态/路由逻辑
    • 依赖变更 (package.json)
  • 后端 Backend

    • API 接口变更
    • 业务逻辑
    • 依赖升级
  • 基础设施 Infrastructure

    • CI/CD 配置
    • 部署脚本
    • 数据库迁移

导入规范检查: 使用别名导入,避免相对路径 ../

变更详情

摘要

添加了3个提供商的frp(但目前只有中文)

动机/背景

提示:可引用 Issue 作为背景说明

让使用者可以在开服的同时方便地进行内网穿透

具体改动

界面变动(如适用)

QQ20260228-221100.mp4
QQ20260301-075954.mp4

关联 Issue

如果不存在关联,此项请忽略

示例:
- Close #123
  关闭 Issue #123
常见关键词 示例
close / closes / closed Close #123
fix / fixes / fixed Fixes #123
resolve / resolves / resolved Resolve #123
其他前缀 用途 示例
ref / references / refs 引用关联,不关闭 Ref #123
related / relates to 表明相关 Related to #123
part of 表明是其中一部分 Part of #123
see / see also 参考其他 Issue See #123
re 关于/回复某个 Issue Re #123
addresses 涉及但未完全解决 Addresses #123
implements 实现某个功能请求 Implements #123
merges 合并相关 Merges #123

自动化审查说明

sourcery-ai 及其他 code review 工具请务必进行中英双语审查与交流。

Note: Please ensure sourcery-ai and other tools perform bilingual (Chinese & English) review.

Summary by Sourcery

添加内置的 FRP 隧道支持,提供专用的 UI 和后端命令,并为多平台打包不同服务商的客户端/服务端配置。

新功能:

  • 在应用中新增 FRP 页面,通过表单使用令牌和隧道 ID,选择服务商来启动隧道。
  • 暴露一个 Tauri 系统命令和前端 API,用于在 Windows、macOS 和 Linux 上为受支持的服务商启动 FRP 隧道。

增强:

  • 打包适用于多种操作系统/架构版本的 FRP(chmlfrp)客户端和服务端配置文件及许可证,以支持新的隧道功能。
Original summary in English

Summary by Sourcery

Add built-in FRP tunneling support with a dedicated UI and backend command, bundling provider-specific client/server configs for multiple platforms.

New Features:

  • Introduce a new FRP page in the app with a form to start tunnels via selected providers using token and tunnel ID.
  • Expose a Tauri system command and frontend API to launch FRP tunnels for supported providers across Windows, macOS, and Linux.

Enhancements:

  • Bundle FRP (chmlfrp) client and server configuration files and licenses for multiple OS/architecture variants to support the new tunneling feature.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Mar 1, 2026

Reviewer's Guide

为三个服务商(OpenFrp、SakuraFrp、ChmlFrp)新增内置的 FRP 内网穿透支持,包括一个新的 UI 页面、用于在各平台拉起服务商专用 frpc 二进制的 Tauri 命令,以及在多种操作系统/架构下打包的 frp 配置/模板和许可证文件。

从新的 FRP UI 启动 FRP 隧道的时序图

sequenceDiagram
    actor User
    participant FRPView as FRPView
    participant SystemApi as systemApi
    participant Tauri as TauriRuntime
    participant SysCmd as system_start_frp_tunnel
    participant FrpcProc as Frpc_process

    User ->> FRPView: Select provider, enter token and tunnelId
    User ->> FRPView: Click startTunnel
    FRPView ->> SystemApi: startFrpTunnel(provider, token, tunnelId)
    SystemApi ->> Tauri: tauriInvoke start_frp_tunnel
    Tauri ->> SysCmd: start_frp_tunnel(provider, token, tunnelId)

    SysCmd ->> SysCmd: Detect OS and ARCH
    SysCmd ->> SysCmd: Map os_name and arch_name
    SysCmd ->> SysCmd: Build frpc_path under app_dir
    alt frpc not found in app_dir
        loop Up to 5 parent directories
            SysCmd ->> SysCmd: Build candidate frpc_path
            SysCmd ->> SysCmd: Check candidate_path.exists()
        end
    end
    SysCmd ->> SysCmd: Validate frpc_path.exists()

    alt provider is chmlfrp or openfrp
        SysCmd ->> SysCmd: Build args -u token -p tunnelId
    else provider is sakurafrp
        SysCmd ->> SysCmd: Build args -f token:tunnelId
    end

    par Spawn frpc in new terminal window
        alt Windows
            SysCmd ->> FrpcProc: cmd.exe /c start cmd.exe /k frpc.exe args
        else macOS
            SysCmd ->> FrpcProc: open -a Terminal frpc args
        else Linux
            SysCmd ->> FrpcProc: xterm|gnome-terminal -e/-- frpc args
        end
    end

    SysCmd -->> Tauri: Ok or error
    Tauri -->> SystemApi: Ok or error
    SystemApi -->> FRPView: Ok or error
    alt success
        FRPView ->> User: Toast 隧道启动成功
    else error
        FRPView ->> User: Toast 隧道启动失败
    end
Loading

File-Level Changes

Change Details Files
Introduce a backend Tauri command to locate and start provider-specific frpc binaries in a new terminal window on all supported platforms.
  • 新增 start_frp_tunnel Tauri 命令,用于解析 OS/架构并构建服务商专用 frpc 可执行文件路径
  • 实现向上遍历目录树的后备搜索逻辑,当在应用目录旁找不到 frpc 二进制时进行查找(方便开发环境)
  • 为 chmlfrp/openfrp(-u/-p)和 sakurafrp(-f token:tunnelId)新增服务商专用的 CLI 参数处理
  • 在独立终端窗口中拉起 frpc,基于 Windows、macOS 和 Linux 不同终端实现平台特定逻辑
  • 将新命令注册到 Tauri 命令列表中,以便前端可以调用
src-tauri/src/commands/system.rs
src-tauri/src/lib.rs
Expose FRP start API to the frontend and add a dedicated FRP settings/view page with basic form-based tunnel launch UI.
  • 扩展 systemApi,增加对新 Tauri 命令的 startFrpTunnel 封装,并重新导出以便直接导入使用
  • 在侧边栏和 Vue 路由中添加新的 /frp 页面入口
  • 创建 FRPView.vue,实现服务商选择、token 和 tunnelId 输入,以及基于 toast 的隧道启动成功/失败提示
  • 为 FRP 表单布局和控件添加局部作用域样式
src/api/system.ts
src/components/layout/AppSidebar.vue
src/router/index.ts
src/views/FRPView.vue
Bundle FRP client/server configuration templates and licenses for ChmlFrp across major OS/architectures, plus a default frpc.ini in the Tauri bundle.
  • 为 chmlfrp 在 linux-amd64、linux-arm64、macos-arm64、windows-amd64 和 windows-arm64 添加 frpc_full.inifrps_full.ini 示例配置
  • 为相同平台添加精简版的 frpc.inifrps.ini 配置,适用于简单场景
  • 为每个平台目录添加占位用 LICENSE 文件
  • 新增 src-tauri/frpc.ini,内含一个针对特定服务器与 Minecraft 端口的具体客户端配置示例
src-tauri/frpc.ini
frpc/chmlfrp/linux-amd64/frpc_full.ini
frpc/chmlfrp/linux-arm64/frpc_full.ini
frpc/chmlfrp/macos-arm64/frpc_full.ini
frpc/chmlfrp/windows-amd64/frpc_full.ini
frpc/chmlfrp/windows-arm64/frpc_full.ini
frpc/chmlfrp/linux-amd64/frps_full.ini
frpc/chmlfrp/linux-arm64/frps_full.ini
frpc/chmlfrp/macos-arm64/frps_full.ini
frpc/chmlfrp/windows-amd64/frps_full.ini
frpc/chmlfrp/windows-arm64/frps_full.ini
frpc/chmlfrp/linux-amd64/frpc.ini
frpc/chmlfrp/linux-arm64/frpc.ini
frpc/chmlfrp/macos-arm64/frpc.ini
frpc/chmlfrp/windows-amd64/frpc.ini
frpc/chmlfrp/windows-arm64/frpc.ini
frpc/chmlfrp/linux-amd64/frps.ini
frpc/chmlfrp/linux-arm64/frps.ini
frpc/chmlfrp/macos-arm64/frps.ini
frpc/chmlfrp/windows-amd64/frps.ini
frpc/chmlfrp/windows-arm64/frps.ini
frpc/chmlfrp/linux-amd64/LICENSE
frpc/chmlfrp/linux-arm64/LICENSE
frpc/chmlfrp/macos-arm64/LICENSE
frpc/chmlfrp/windows-amd64/LICENSE
frpc/chmlfrp/windows-arm64/LICENSE

Possibly linked issues

  • #: PR 实现侧边栏 FRP 页面与 start_frp_tunnel,集成 openfrp 等,实现 Issue 所需的内网穿透功能。

Tips and commands

Interacting with Sourcery

  • Trigger a new review: 在 pull request 中评论 @sourcery-ai review 以触发新一轮代码审查。
  • Continue discussions: 直接回复 Sourcery 的审查评论以继续讨论。
  • Generate a GitHub issue from a review comment: 在某条审查评论下回复,请求 Sourcery 基于该评论创建 issue。你也可以直接回复 @sourcery-ai issue,由此从该评论生成 issue。
  • Generate a pull request title: 在 pull request 标题任意位置写上 @sourcery-ai,即可随时生成标题。也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • Generate a pull request summary: 在 pull request 正文任意位置写上 @sourcery-ai summary,即可在相应位置生成 PR 总结。也可以在 pull request 中评论 @sourcery-ai summary 来(重新)生成总结。
  • Generate reviewer's guide: 在 pull request 中评论 @sourcery-ai guide,即可随时(重新)生成 Reviewer's Guide。
  • Resolve all Sourcery comments: 在 pull request 中评论 @sourcery-ai resolve,将所有 Sourcery 评论标记为已解决。如果你已经处理完所有评论且不想继续看到它们,这会很有用。
  • Dismiss all Sourcery reviews: 在 pull request 中评论 @sourcery-ai dismiss,以撤销所有现有的 Sourcery 审查。想要从零开始新一轮审查时特别有用——别忘了再评论一次 @sourcery-ai review 以触发新审查!

Customizing Your Experience

在你的 dashboard 中可以:

  • 启用或关闭诸如 Sourcery 自动生成的 PR 总结、Reviewer's Guide 等审查功能。
  • 修改审查语言。
  • 添加、删除或编辑自定义审查指令。
  • 调整其他审查相关设置。

Getting Help

Original review guide in English

Reviewer's Guide

Adds built-in FRP tunneling support for three providers (OpenFrp, SakuraFrp, ChmlFrp) including a new UI page, Tauri command to spawn provider-specific frpc binaries across platforms, and bundled frp config/templates and licenses for multiple OS/architectures.

Sequence diagram for starting an FRP tunnel from the new FRP UI

sequenceDiagram
    actor User
    participant FRPView as FRPView
    participant SystemApi as systemApi
    participant Tauri as TauriRuntime
    participant SysCmd as system_start_frp_tunnel
    participant FrpcProc as Frpc_process

    User ->> FRPView: Select provider, enter token and tunnelId
    User ->> FRPView: Click startTunnel
    FRPView ->> SystemApi: startFrpTunnel(provider, token, tunnelId)
    SystemApi ->> Tauri: tauriInvoke start_frp_tunnel
    Tauri ->> SysCmd: start_frp_tunnel(provider, token, tunnelId)

    SysCmd ->> SysCmd: Detect OS and ARCH
    SysCmd ->> SysCmd: Map os_name and arch_name
    SysCmd ->> SysCmd: Build frpc_path under app_dir
    alt frpc not found in app_dir
        loop Up to 5 parent directories
            SysCmd ->> SysCmd: Build candidate frpc_path
            SysCmd ->> SysCmd: Check candidate_path.exists()
        end
    end
    SysCmd ->> SysCmd: Validate frpc_path.exists()

    alt provider is chmlfrp or openfrp
        SysCmd ->> SysCmd: Build args -u token -p tunnelId
    else provider is sakurafrp
        SysCmd ->> SysCmd: Build args -f token:tunnelId
    end

    par Spawn frpc in new terminal window
        alt Windows
            SysCmd ->> FrpcProc: cmd.exe /c start cmd.exe /k frpc.exe args
        else macOS
            SysCmd ->> FrpcProc: open -a Terminal frpc args
        else Linux
            SysCmd ->> FrpcProc: xterm|gnome-terminal -e/-- frpc args
        end
    end

    SysCmd -->> Tauri: Ok or error
    Tauri -->> SystemApi: Ok or error
    SystemApi -->> FRPView: Ok or error
    alt success
        FRPView ->> User: Toast 隧道启动成功
    else error
        FRPView ->> User: Toast 隧道启动失败
    end
Loading

File-Level Changes

Change Details Files
Introduce a backend Tauri command to locate and start provider-specific frpc binaries in a new terminal window on all supported platforms.
  • Add start_frp_tunnel Tauri command that resolves OS/arch and builds provider-specific frpc executable paths
  • Implement fallback search up the directory tree for frpc binaries when not found alongside the app (dev environment support)
  • Add provider-specific CLI argument handling for chmlfrp/openfrp (-u/-p) and sakurafrp (-f token:tunnelId)
  • Spawn frpc in a separate terminal window with platform-specific logic for Windows, macOS, and Linux terminals
  • Wire the new command into the Tauri command list so it can be invoked from the frontend
src-tauri/src/commands/system.rs
src-tauri/src/lib.rs
Expose FRP start API to the frontend and add a dedicated FRP settings/view page with basic form-based tunnel launch UI.
  • Extend systemApi with startFrpTunnel wrapper around the new Tauri command and re-export it for direct import
  • Add sidebar navigation entry and Vue router route for the new /frp page
  • Create FRPView.vue implementing provider selection, token and tunnelId inputs, and toast-based success/error handling when starting tunnels
  • Apply local scoped styling for the FRP form layout and controls
src/api/system.ts
src/components/layout/AppSidebar.vue
src/router/index.ts
src/views/FRPView.vue
Bundle FRP client/server configuration templates and licenses for ChmlFrp across major OS/architectures, plus a default frpc.ini in the Tauri bundle.
  • Add frpc_full.ini and frps_full.ini example configs for chmlfrp for linux-amd64, linux-arm64, macos-arm64, windows-amd64, and windows-arm64
  • Add minimal frpc.ini and frps.ini configs for the same platforms for simpler setups
  • Add placeholder LICENSE files for each chmlfrp platform directory
  • Add src-tauri/frpc.ini with a concrete example client config targeting a specific server and Minecraft port
src-tauri/frpc.ini
frpc/chmlfrp/linux-amd64/frpc_full.ini
frpc/chmlfrp/linux-arm64/frpc_full.ini
frpc/chmlfrp/macos-arm64/frpc_full.ini
frpc/chmlfrp/windows-amd64/frpc_full.ini
frpc/chmlfrp/windows-arm64/frpc_full.ini
frpc/chmlfrp/linux-amd64/frps_full.ini
frpc/chmlfrp/linux-arm64/frps_full.ini
frpc/chmlfrp/macos-arm64/frps_full.ini
frpc/chmlfrp/windows-amd64/frps_full.ini
frpc/chmlfrp/windows-arm64/frps_full.ini
frpc/chmlfrp/linux-amd64/frpc.ini
frpc/chmlfrp/linux-arm64/frpc.ini
frpc/chmlfrp/macos-arm64/frpc.ini
frpc/chmlfrp/windows-amd64/frpc.ini
frpc/chmlfrp/windows-arm64/frpc.ini
frpc/chmlfrp/linux-amd64/frps.ini
frpc/chmlfrp/linux-arm64/frps.ini
frpc/chmlfrp/macos-arm64/frps.ini
frpc/chmlfrp/windows-amd64/frps.ini
frpc/chmlfrp/windows-arm64/frps.ini
frpc/chmlfrp/linux-amd64/LICENSE
frpc/chmlfrp/linux-arm64/LICENSE
frpc/chmlfrp/macos-arm64/LICENSE
frpc/chmlfrp/windows-amd64/LICENSE
frpc/chmlfrp/windows-arm64/LICENSE

Possibly linked issues

  • #: PR 实现侧边栏 FRP 页面与 start_frp_tunnel,集成 openfrp 等,实现 Issue 所需内网穿透功能。

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

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了 5 个问题,并且给出了一些整体性的反馈:

  • start_frp_tunnel 在 Windows 分支中构建 cmd.exe 命令行时,没有对 frpc 路径或参数进行引号包裹,这会导致包含空格的路径出错;可以通过为可执行文件路径和任何用户提供的参数加上引号来提升健壮性。
  • FRP 配置文件 src-tauri/frpc.ini 中似乎包含真实的服务器地址、用户和 token(ChmlFrpToken);建议移除或匿名化任何真实凭据,并通过用户配置加载这些信息,而不是直接提交到仓库。
  • 针对每个 provider 的 FRP 二进制/配置查找逻辑在多个 match 分支以及向上目录搜索时都有重复;可以抽取一个小的辅助函数,只构建一次针对特定 provider 的 frpc 路径,从而简化 start_frp_tunnel,并减少不同分支随时间产生逻辑偏差的风险。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The Windows branch of `start_frp_tunnel` builds a `cmd.exe` command line without quoting the `frpc` path or arguments, which will break for paths containing spaces and can be made more robust by wrapping the executable path and any user-provided arguments in quotes.
- The FRP config `src-tauri/frpc.ini` contains what looks like a real server address, user and token (`ChmlFrpToken`); consider removing or anonymizing any real credentials and loading this information from user configuration instead of committing it to the repo.
- The FRP binary/config lookup logic for each provider is duplicated in multiple match arms and again in the upward-directory search; extracting a small helper to build the provider-specific `frpc` path once would simplify `start_frp_tunnel` and reduce the chance of the branches diverging over time.

## Individual Comments

### Comment 1
<location path="src-tauri/src/commands/system.rs" line_range="346-347" />
<code_context>
     Ok(())
 }
+
+#[tauri::command]
+pub fn start_frp_tunnel(provider: String, token: String, tunnel_id: String) -> Result<(), String> {
+    // 确定系统和架构
+    let os = std::env::consts::OS;
</code_context>
<issue_to_address>
**🚨 issue (security):** Passing token and tunnel ID as CLI args exposes them in process lists; consider a safer way to pass secrets.

The FRP token and tunnel ID are always passed via CLI args in the base `command` and all platform-specific launchers. On most systems, process arguments are visible to other users (ps, Task Manager, etc.), so this can leak credentials. If FRP supports config files, env vars, or stdin for credentials, prefer those and avoid putting secrets on the command line.
</issue_to_address>

### Comment 2
<location path="src-tauri/src/commands/system.rs" line_range="451-453" />
<code_context>
+    #[cfg(target_os = "windows")]
+    {
+        // 在Windows上使用start命令打开新窗口
+        let frpc_path_str = frpc_path.to_str().unwrap();
+        // 转换为Windows风格的路径
+        let windows_path = frpc_path_str.replace('/', "\\");
+        // 构建命令参数
+        let mut cmd = std::process::Command::new("cmd.exe");
</code_context>
<issue_to_address>
**issue (bug_risk):** Avoid `to_str().unwrap()` on paths; handle non-UTF8 paths more defensively.

On Windows this will panic if `frpc_path` contains non‑UTF‑8 data, causing the command to crash. Prefer `to_string_lossy()` or explicitly handle the `None` case from `to_str()` and map it to your `Result<(), String>` instead of unwrapping.
</issue_to_address>

### Comment 3
<location path="src/views/FRPView.vue" line_range="14" />
<code_context>
+      </div>
+      <div class="form-row">
+        <label class="form-label">token</label>
+        <input type="text" class="form-input" placeholder="粘贴token" v-model="token" />
+      </div>
+      <div class="form-row">
</code_context>
<issue_to_address>
**🚨 issue (security):** Token is collected in a plain text field; consider treating it as a secret.

This field uses a standard `type="text"` input, so the token is fully visible on screen and may end up in browser autofill history. Using `type="password"` (optionally with a visibility toggle) would better protect the token from shoulder surfing and accidental exposure while still allowing copy/paste.
</issue_to_address>

### Comment 4
<location path="src/views/FRPView.vue" line_range="37-44" />
<code_context>
+const tunnelId = ref("");
+const { success, error } = useToast();
+
+async function startTunnel() {
+  if (!token.value || !tunnelId.value) {
+    error("请填写完整信息");
+    return;
+  }
+
+  try {
+    await startFrpTunnel(provider.value, token.value, tunnelId.value);
+    success("隧道启动成功");
+  } catch (err) {
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider disabling the button or handling concurrent clicks while the tunnel is starting.

Multiple rapid clicks on “启动隧道” will call `startFrpTunnel` in parallel and may start duplicate tunnels or surface confusing errors. Consider guarding with an `isStarting` flag to prevent re-entry (e.g., disable the button and/or show a loading state while the async call is in progress).

Suggested implementation:

```
const provider = ref("openfrp");
const token = ref("");
const tunnelId = ref("");
const { success, error } = useToast();
const isStarting = ref(false);

async function startTunnel() {
  if (isStarting.value) {
    // 防止重复点击导致并发请求
    return;
  }

  if (!token.value || !tunnelId.value) {
    error("请填写完整信息");
    return;
  }

  isStarting.value = true;

  try {
    await startFrpTunnel(provider.value, token.value, tunnelId.value);
    success("隧道启动成功");
  } catch (err) {
    error("隧道启动失败");
    console.error(err);
  } finally {
    isStarting.value = false;
  }
}

```

1. In the `<template>` for this view, bind the "启动隧道" button's `disabled` (and/or loading) state to `isStarting`, for example:
   - `:disabled="isStarting"` or `:loading="isStarting"` depending on your UI library.
2. If you're using a custom button component (e.g. from Element Plus, Naive UI, etc.), follow its existing pattern for showing loading states to visually indicate that the tunnel is starting.
</issue_to_address>

### Comment 5
<location path="src-tauri/frpc.ini" line_range="1-7" />
<code_context>
+[common]
+server_addr = 127.0.0.1
+server_port = 7000
</code_context>
<issue_to_address>
**🚨 issue (security):** Committed FRP config contains concrete server address, user and token, which may be sensitive.

If these values (including any `user`/`token` in this file) are real credentials, they shouldn’t be committed. Please replace with clearly fake placeholders and load any secrets from environment or user input instead, to avoid accidental leakage.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Original comment in English

Hey - I've found 5 issues, and left some high level feedback:

  • The Windows branch of start_frp_tunnel builds a cmd.exe command line without quoting the frpc path or arguments, which will break for paths containing spaces and can be made more robust by wrapping the executable path and any user-provided arguments in quotes.
  • The FRP config src-tauri/frpc.ini contains what looks like a real server address, user and token (ChmlFrpToken); consider removing or anonymizing any real credentials and loading this information from user configuration instead of committing it to the repo.
  • The FRP binary/config lookup logic for each provider is duplicated in multiple match arms and again in the upward-directory search; extracting a small helper to build the provider-specific frpc path once would simplify start_frp_tunnel and reduce the chance of the branches diverging over time.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The Windows branch of `start_frp_tunnel` builds a `cmd.exe` command line without quoting the `frpc` path or arguments, which will break for paths containing spaces and can be made more robust by wrapping the executable path and any user-provided arguments in quotes.
- The FRP config `src-tauri/frpc.ini` contains what looks like a real server address, user and token (`ChmlFrpToken`); consider removing or anonymizing any real credentials and loading this information from user configuration instead of committing it to the repo.
- The FRP binary/config lookup logic for each provider is duplicated in multiple match arms and again in the upward-directory search; extracting a small helper to build the provider-specific `frpc` path once would simplify `start_frp_tunnel` and reduce the chance of the branches diverging over time.

## Individual Comments

### Comment 1
<location path="src-tauri/src/commands/system.rs" line_range="346-347" />
<code_context>
     Ok(())
 }
+
+#[tauri::command]
+pub fn start_frp_tunnel(provider: String, token: String, tunnel_id: String) -> Result<(), String> {
+    // 确定系统和架构
+    let os = std::env::consts::OS;
</code_context>
<issue_to_address>
**🚨 issue (security):** Passing token and tunnel ID as CLI args exposes them in process lists; consider a safer way to pass secrets.

The FRP token and tunnel ID are always passed via CLI args in the base `command` and all platform-specific launchers. On most systems, process arguments are visible to other users (ps, Task Manager, etc.), so this can leak credentials. If FRP supports config files, env vars, or stdin for credentials, prefer those and avoid putting secrets on the command line.
</issue_to_address>

### Comment 2
<location path="src-tauri/src/commands/system.rs" line_range="451-453" />
<code_context>
+    #[cfg(target_os = "windows")]
+    {
+        // 在Windows上使用start命令打开新窗口
+        let frpc_path_str = frpc_path.to_str().unwrap();
+        // 转换为Windows风格的路径
+        let windows_path = frpc_path_str.replace('/', "\\");
+        // 构建命令参数
+        let mut cmd = std::process::Command::new("cmd.exe");
</code_context>
<issue_to_address>
**issue (bug_risk):** Avoid `to_str().unwrap()` on paths; handle non-UTF8 paths more defensively.

On Windows this will panic if `frpc_path` contains non‑UTF‑8 data, causing the command to crash. Prefer `to_string_lossy()` or explicitly handle the `None` case from `to_str()` and map it to your `Result<(), String>` instead of unwrapping.
</issue_to_address>

### Comment 3
<location path="src/views/FRPView.vue" line_range="14" />
<code_context>
+      </div>
+      <div class="form-row">
+        <label class="form-label">token</label>
+        <input type="text" class="form-input" placeholder="粘贴token" v-model="token" />
+      </div>
+      <div class="form-row">
</code_context>
<issue_to_address>
**🚨 issue (security):** Token is collected in a plain text field; consider treating it as a secret.

This field uses a standard `type="text"` input, so the token is fully visible on screen and may end up in browser autofill history. Using `type="password"` (optionally with a visibility toggle) would better protect the token from shoulder surfing and accidental exposure while still allowing copy/paste.
</issue_to_address>

### Comment 4
<location path="src/views/FRPView.vue" line_range="37-44" />
<code_context>
+const tunnelId = ref("");
+const { success, error } = useToast();
+
+async function startTunnel() {
+  if (!token.value || !tunnelId.value) {
+    error("请填写完整信息");
+    return;
+  }
+
+  try {
+    await startFrpTunnel(provider.value, token.value, tunnelId.value);
+    success("隧道启动成功");
+  } catch (err) {
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider disabling the button or handling concurrent clicks while the tunnel is starting.

Multiple rapid clicks on “启动隧道” will call `startFrpTunnel` in parallel and may start duplicate tunnels or surface confusing errors. Consider guarding with an `isStarting` flag to prevent re-entry (e.g., disable the button and/or show a loading state while the async call is in progress).

Suggested implementation:

```
const provider = ref("openfrp");
const token = ref("");
const tunnelId = ref("");
const { success, error } = useToast();
const isStarting = ref(false);

async function startTunnel() {
  if (isStarting.value) {
    // 防止重复点击导致并发请求
    return;
  }

  if (!token.value || !tunnelId.value) {
    error("请填写完整信息");
    return;
  }

  isStarting.value = true;

  try {
    await startFrpTunnel(provider.value, token.value, tunnelId.value);
    success("隧道启动成功");
  } catch (err) {
    error("隧道启动失败");
    console.error(err);
  } finally {
    isStarting.value = false;
  }
}

```

1. In the `<template>` for this view, bind the "启动隧道" button's `disabled` (and/or loading) state to `isStarting`, for example:
   - `:disabled="isStarting"` or `:loading="isStarting"` depending on your UI library.
2. If you're using a custom button component (e.g. from Element Plus, Naive UI, etc.), follow its existing pattern for showing loading states to visually indicate that the tunnel is starting.
</issue_to_address>

### Comment 5
<location path="src-tauri/frpc.ini" line_range="1-7" />
<code_context>
+[common]
+server_addr = 127.0.0.1
+server_port = 7000
</code_context>
<issue_to_address>
**🚨 issue (security):** Committed FRP config contains concrete server address, user and token, which may be sensitive.

If these values (including any `user`/`token` in this file) are real credentials, they shouldn’t be committed. Please replace with clearly fake placeholders and load any secrets from environment or user input instead, to avoid accidental leakage.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant