npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wanxiangbaiying

v0.1.1

Published

Framework-neutral third-party OAuth login with Electron host adapter

Readme

wanxiangbaiying:万象百应登录 SDK

2026-09-16,内部开发版 0.1.1。npm 包名为 wanxiangbaiying,API 名称 initWanxiangLogin / wanxiangLogin 与浏览器构建 wanxiangLogin.js 保持不变。SDK 专供三方应用接入万象授权;平台客户端的授权服务直接实现在平台项目内,不安装、不引用此 SDK。Mac/Windows 使用同一份 JS 实现,目前不验证发行签名,没有 C++、.node、OS 模块构建或额外资源复制步骤。

npm registry 当前已发布 0.1.0;本目录的 0.1.1 设备标识修复发布前,可执行 npm install ../wanxiang-login-sdk(替换为实际相对路径)做本地联调。发布后使用 npm install [email protected]。源码目录名和 npm 包名是独立的;改包名不改变平台本地协议 wanxiang-login 或应用的 clientId / scheme。

SDK 与应用各自负责什么

SDK 编排登录:探测已运行的平台 → 创建授权请求 → 原生确认或系统浏览器 → PKCE/回环校验 → 换票 → 返回结果;另提供取消、主动刷新和撤销方法。

SDK 不依赖 Vue、React、Pinia 或其他状态库,不保存登录结果,不创建业务用户,不调用三方自己的业务后端,不自动安排刷新。 应用自己决定如何使用/保存返回的 session、何时刷新以及如何建立自己的业务会话。万象开工使用 Pinia 是它自己的选择。

请求执行中必须临时持有 state/verifier/授权码等材料;执行完清理引用。成功后仅保留 openId/token 的不可逆摘要和本地代次,用于拦截串号刷新与过期异步结果,不保留完整 session、原始 token 或用户资料。clearSession() 只清这些校验信息、取消旧请求;不会替应用清自己的状态。

另有两个不含登录凭据的本地数据:SDK 在应用 userData 写随机 oauth-install-id,用于设备登记;平台运行时在当前用户目录发布短暂端口/握手记录。它们都不是接口登录结果,也不是 token 存储。SDK 不使用 Keychain、DPAPI、localStorage 或 Cookie 存 token。设备 ID 在标识文件确实不存在时才创建;文件损坏或暂时无法读取会明确失败,不会静默换一个 ID。并发首次启动也复用同一份标识。

设备登记默认上报经过清洗、截断且移除 .local 后缀的系统主机名,以及可读的操作系统名称和版本(例如 macOS 15.6.1);不读取硬盘序列号、网卡地址等硬件标识。接入方如有隐私或命名要求,可继续通过 getDeviceFields 覆盖这些展示字段。

Electron 接入:初始化一次,页面直接调用

创建主窗口后、首次 loadURL/loadFile 之前初始化:

import { initWanxiangLogin } from 'wanxiangbaiying/electron/main'

initWanxiangLogin({
  platformOrigin: 'https://platform.example.com',
  appId: 'your-app',
  clientIds: { MAC: 'your_app_mac', WINDOWS: 'your_app_windows' },
})

页面按钮调用:

import { wanxiangLogin } from 'wanxiangbaiying/renderer'

const result = await wanxiangLogin.signIn()
if (result.kind === 'success') {
  // 应用自己处理 result.session:更新状态、同步业务后端等。
}

没有第三段 preload 接入,也不再手写 attach/detach/closed/before-quit 清理。 SDK 自动注册自己的 sandbox 预加载脚本、绑定主窗口首次由应用发起的页面加载,并在关闭窗口/退出时清理。页面重载或跳到其他地址不会获得额外权限,其他窗口和 iframe 不获得登录 bridge。

window 可省略:初始化时只有一个尚未加载页面的应用窗口,就自动绑定它;存在多个窗口时传 window: mainWindow 明确指定,尚未创建窗口时会提示先创建。绑定后不跟随窗口焦点或后续新窗口改变,不需要额外填写 documentUrl。初始化后仍按应用原有逻辑调用 loadURL/loadFile。SDK 的 JS 文件随 npm 依赖正常打包,无需修改应用 preload、复制资源或安装构建插件;不要从最终应用中排除整个 SDK 依赖。

openBrowser 可省略,默认由 SDK 调用 Electron shell.openExternal(url) 打开系统默认浏览器。需要自定义时传 openBrowser: url => applicationOpenBrowser(url) 覆盖;支持返回 void 或 Promise。SDK 仍校验授权 URL 并等待回环。SDK 不决定登录后如何切页、聚焦或保存结果;需要登录后聚焦时可提供 focusApplication 回调。

本地开发可用目录 file: 安装,正式构建应固定 npm 版本。自动初始化已在 Electron43 验证,使用其 registerPreloadScript 能力;不支持该能力的旧版本会明确报错,不退回要求接入方手写桥接。开发 HTTP origin 需加 allowInsecureDevelopmentOrigin:true。

已自动处理与仍需配置的内容

| 项目 | 当前行为 | | --- | --- | | runtime | 不再提供此配置;页面依据宿主桥接能力自动选择 | | Mac/Windows | Electron 主进程用真实 process.platform 选择对应 clientId | | platformOrigin / appId / clientIds | 必填;来自平台登记,不能根据 OS、应用名称或 appId 猜 clientId | | callbackPaths | 可省,默认 MAC /oauth/mac/callback、WINDOWS /oauth/windows/callback;平台必须已登记对应回环模板,若登记路径不同再覆盖 | | scopes | 可省,默认仅 ['profile:read'];需 AI、任务、刷新等能力时显式申请对应 scope | | requiredScopes | 可选;应用运行确实不可缺少的 scope,用于校验返回结果 | | appScheme | 普通登录可省;平台市场唤起/浏览器页“打开应用”按钮需要填写并由应用注册自己的协议 | | window | 可省,自动绑定初始化时唯一的应用窗口;多窗口时必须指定,不自动选择焦点窗口 | | openBrowser | 可省,默认 Electron shell.openExternal;传入函数可覆盖 | | productName / focusApplication | 名称默认取 Electron app;聚焦行为由应用按需提供,不自动决定 | | 探测/设备/端口/PKCE/state | SDK 自动完成,无需填写平台安装路径、端口、deviceId、签名或通信代码 |

只发行一个系统的应用只填对应 clientIds 项即可。双端发行使用同一份配置,无需每端改代码。默认回调只是现有后端可接受的登记约定,不会替你修改登记;SDK 不能匿名查询 /app/market/{appId} 来补配置。

appId 标识整个应用,clientIds.MAC / clientIds.WINDOWS 是平台为该应用分别登记的 Mac / Windows 公开接入端编号,用来选择该端的回调白名单、权限和原生登录能力。它们不是用户 ID、密钥或唤起协议名;示例里的编号不能自行拼接代替真实登记值。开发者填写一次,SDK 按实际系统自动选择,用户不需要填写。

需要自动续期时显式加 scopes:['profile:read','offline_access']。授权结果里的 refreshToken 可能为空;只有获得刷新票时才能刷新。

页面 API 与数据所有权

const login = wanxiangLogin
const availability = await login.getAvailability() // ready 才适合显示快捷登录
const stop = login.onProgress(event => { /* 更新等待界面 */ })
await login.signIn()                           // 默认 auto,用户触发
await login.signIn({ mode: 'browser' })        // 用户明确选择浏览器
await login.cancel()                          // 取消正在进行的授权
const updated = await login.refresh(refreshToken) // 调用方提供刷新票,自己接收新 session
await login.revoke(refreshToken || accessToken)   // 调用方提供需要撤销的票
stop()                                        // 移除本订阅
// login.dispose() 会移除订阅并取消当前登录;不清业务状态、不代替退出。

以上是独立调用示例,不是在一次登录里顺序执行。成功结果为 {kind:'success',channel:'native'|'browser',session};session 包含 appId/clientId/openId/accessToken/refreshToken/tokenType/scopes/expiresIn/expiresAt,可含 installId。取消和错误以带 code、可选 requestId 的 Error 拒绝 Promise。

应用负责唯一的刷新调度;用 login.refresh 返回的新结果替换自己保存的旧结果。退出先停止调度、清本地业务状态并取消旧请求,再尽力撤销此前持有的票。SDK 不清应用的 store、不自动把 token 注入业务 HTTP。业务后端必须可信自省,按 (platformId, appId, openId) 建用户,不能信页面自报的 openId。

授权与唤起

平台已运行、已登录且目标公开 client 开启 native 时,默认优先原生账号/权限确认。平台关闭、未登录、能力不支持或本地不可用时,打开平台后端 /consent/index.html?authRequestId=...。不自动启动平台;用户拒绝结束请求,不转浏览器再问一遍。

本地发现以平台 origin 隔离,通信使用 127.0.0.1 随机端口和双向 HMAC 握手。发现记录仅含端口、PID 和本地随机握手材料;CUSTOMER token 留在平台。当前不核验发行者,握手不抵御能读写当前用户目录的恶意程序;后端授权、用户确认与 PKCE/state 校验继续保留。

同产品 Mac/Windows 可共用 appScheme,clientId 分开。应用主进程接系统 open-url/second-instance,用 parseLaunchUrl(url, scheme) 校验。scheme://activate 只聚焦;scheme://launch?ticket=lt_... 交 初始化返回实例的 signInFromLaunch(ticket) 并把成功结果交给应用自己的业务登录处理。协议注册/冷启动排队属于应用生命周期,万象开工已有实现;市场 launch_ticket 不是普通反向登录请求的凭据。

普通 Web 网站可以不用 SDK

当前 Web 入口只跳转到网站自己的登录后端(BFF),不包含完整 Web OAuth 服务端流程,不做本机平台探测。普通链接已经足够:

<a href="/auth/wanxiang/start">使用万象账号登录</a>

这个路径是网站需要自己实现的示例,不是 SDK 创建的接口。网站后端按已登记 WEB client 处理 state、PKCE、回调、换票和 HttpOnly 会话 Cookie,密钥留在网站后端。平台市场的 entryUrl 是网站首页,不是本机回环地址。

若多端共用按钮逻辑,可选以下轻量包装,仍不填 runtime:

import { WanxiangLogin } from 'wanxiangbaiying/web'
const login = new WanxiangLogin({ loginStartUrl: '/auth/wanxiang/start' })
// 用户点击:await login.signIn(),只进行同源导航,返回 {kind:'redirecting'}。

普通网站无需 main/preload,不注册桌面 scheme;refresh/revoke 桌面 API 不用于网站,网站通过自己的后端管理会话。

非 Electron 客户端

| 应用技术 | 已实现能力 / 还需做什么 | | --- | --- | | Electron + 任意页面框架 | 初始化 + 页面调用,bridge/窗口绑定/清理由 SDK 内置,不要求 Vue/Pinia | | 其他具备 Node 的桌面宿主 | 可复用 wanxiangbaiying/core、/protocol,宿主补系统浏览器、生命周期与界面桥接;当前未提供这些宿主的一键适配器 | | Tauri、Qt WebEngine、WebView2 等 WebView 应用 | 可复用页面 JS API,宿主需实现 LoginBridge,以相同全局名暴露或传 new WanxiangLogin({bridge});当前未交付 Rust/C++/C# 原生适配器 | | 纯 Swift/AppKit、C#/WPF、Qt 原生 UI | 不能直接执行依赖 Node 的 JS 核心;需对应语言 SDK/薄适配层,复用现有后端 OAuth 和本地协议 | | 普通 Web 网站 | 直接用网站登录链接;此 JS 包是可选按钮包装 |

统一的是授权契约,不是让任何语言都能直接导入 .js。新增框架时由 SDK 维护方补相应适配器即可,不要求平台客户端重新实现授权,也不要求平台后端增加同义接口。当前支持的桌面操作系统为 Mac/Windows,移动端与 Linux 未交付。

维护者验证

npm run check
npm test
npm run test:platform
npm run test:native
npm run test:native:bundle
npm run test:auto-init
npm run test:asar

npm test 可独立跑 SDK 测试。test:platform 是跨项目协议测试,默认读取相邻 ../FangMao/fe-fangmao-platform,可用 WANXIANG_PLATFORM_PROJECT 指定平台源码路径;这只用于维护者测试,不是三方安装或运行依赖。Electron 烟测使用相邻万象开工的 Electron/Vite。

SDK 34 项测试通过,包含稳定设备标识、并发首次启动、损坏标识保护、自动选择唯一窗口、多窗口显式绑定、默认系统浏览器与自定义覆盖。此次参数简化还通过万象开工类型检查、23 项授权测试和真实 Mac Electron 打包主进程烟测(含窗口隔离、原生授权、PKCE/回环;云端为夹具)。此前跨项目互通 9 项、应用自有 preload 共存和 app.asar 内加载测试已通过。平台本地模块无需 SDK 就能加载运行。Windows 真机、真实短信/平台服务与安装包唤起仍需验收;没有为这些测试发布安装包。