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

@qfeius/make-app-auth

v0.1.2

Published

Browser SDK for Make generated app authentication through make-gateway.

Readme

Make App Auth SDK

@qfeius/make-app-auth 是 Make 生成 App 的浏览器认证 SDK。

它只做薄封装:

  • 检查当前 App 会话:GET /api/make/auth/current-context
  • 未登录时按网关返回的 authorizationUrl 跳转 Org 登录
  • Org 回调由 make-gateway 直接换 token,并 302 到 App 域名下的 session complete 接口落 make_app_session
  • 退出账号:调用网关退出接口,由 make-gateway 后端清 Org 委托 token 和当前 App 会话,再回到 App 入口复用登录判断
  • 业务请求遇到 401/403 时给出统一处理
  • 当后端明确关闭统一登录时,改用调用方指定 token 或本地 makecli credentials token

SDK 不保存 Org token,不拼接 Org OAuth 参数,不负责 OAuth code exchange,不解析可信身份头。认证复杂逻辑仍在 make-gateway。token 模式只用于后端显式关闭统一登录的场景。

安装

公共 npm 依赖:

pnpm add @qfeius/make-app-auth --registry=https://registry.npmjs.org/

本地联调:

pnpm add /Users/apple/code/make/make-app-auth-sdk

最小接入

import { createMakeAppAuth } from '@qfeius/make-app-auth';

const auth = createMakeAppAuth({
  gatewayBaseUrl: '/api/make',
  apiAuthRedirect: true
});

const result = await auth.init({ redirect: true });

if (result.status === 'authenticated') {
  renderApp({
    auth,
    context: result.context
  });
} else if (result.status === 'redirecting') {
  renderLoading();
} else if (result.reason === 'state_expired' || result.reason === 'challenge_expired') {
  renderLoginExpired({
    message: result.message || '登录已过期,请重新登录',
    onRelogin: () => auth.login({ redirect: true })
  });
} else if (result.status === 'forbidden') {
  renderForbidden();
} else {
  await auth.login({ redirect: true });
}

init 是生成 App 的推荐启动入口。它会访问:

GET /api/make/auth/current-context?return_url=当前页面地址

返回含义:

  • authenticated:已有当前 App 会话,可以渲染页面。
  • authenticated + context.authMode="token":后端关闭统一登录,SDK 已切到 token 模式。
  • redirecting:未登录且已跳转到网关返回的 authorizationUrl
  • unauthenticated:未登录,但调用方指定了 redirect: false 或跳转保护已触发。
  • unauthenticated + reason="state_expired" / "challenge_expired":登录过程已过期,页面应提示“登录已过期,请重新登录”,用户点击后调用 auth.login({ redirect: true })
  • forbidden:已登录但无权访问当前 App。
  • failed:网关返回了非预期错误。

如果只需要页面可见的精简运行态信息,也可以继续使用:

const runtimeView = await auth.getRuntimeView();

如果需要当前用户、租户、App 上下文,使用:

const context = await auth.getCurrentContext();

登录回调链路

正式链路下,Org OAuth redirect_uri 固定回到 make-gateway。make-gateway 会直接用 code 换 Org token,生成一次性 login_ticket,再跳到当前 App 域名下:

GET /api/make/auth/session/complete?login_ticket=...

这个请求由 App 域名代理到 make-gateway。网关消费 login_ticket 后写入 make_app_session,再 302 回原始 App 页面。

因此,新 App 不需要主动调用 handleOAuthCallback()init() 默认也不会处理 URL 上的 code/state,避免把业务参数误判成 OAuth 回调。

这个方法只作为旧链路兼容保留:如果页面 URL 里仍出现旧版 OAuth 回调参数,可以显式开启 legacy 模式完成旧版 exchange。

await auth.init({ legacyOAuthCallback: true });
POST /api/make/oauth/token/exchange

业务请求

业务接口继续统一走 make-gateway:

const records = await auth.api.post('/data/v1/record', {
  app: 'expense',
  entity: 'reimbursement',
  fields: [],
  pagination: { page: 1, size: 10 }
}, {
  headers: {
    'X-Make-Target': 'MakeService.ListResources'
  }
});

auth.api 是生成 App 的推荐业务请求入口,会默认补 credentials: 'include'Accept: application/json,并对普通对象自动 JSON 序列化。 调用方可以在 init.headers 里传业务需要的 header,例如 X-Make-TargetX-Trace-IdX-Idempotency-Key,也可以覆盖默认 AcceptContent-Type。 设置 apiAuthRedirect: true 后,统一登录模式下业务请求遇到 401/403 会先复用 auth.login({ redirect: true }) 获取网关登录挑战并跳转;如果跳转保护已触发或网关没有返回登录挑战,SDK 仍会抛出对应错误,避免无限循环。token 模式不会跳 Org。

如果 App 采用 Service 承接业务编排,业务路径也应继续放在 gatewayBaseUrl 作用域内,例如:

await auth.api.get('/app/schema');
await auth.api.post('/app/records/customer', payload);

这类请求的浏览器链路是:

UI -> /api/make/app/** -> App Service -> make-gateway /make/meta|data/**

认证链路仍是:

UI -> /api/make/auth/** -> App Service proxy -> make-gateway /api/make/auth/**

Service 代理 /api/make/auth/session/complete 时必须保留网关返回给浏览器的 302 + Set-Cookie + Location,不要在 Service 内部跟随重定向。

如果后端返回统一登录关闭标记,SDK 会进入 token 模式,后续 auth.api 自动补:

Authorization: Bearer <token>

token 来源优先级:

  1. createMakeAppAuth({ accessToken })token
  2. tokenProvider()
  3. Node/本地环境读取 credentialsPath,默认 /Users/apple/.make/credentials 等价的 ~/.make/credentials

浏览器不能直接读取本机文件,所以浏览器场景要通过 accessTokentokenProvider 显式传入;credentials 文件兜底只适合 Node、本地调试或测试环境。

本地 vibe 项目如果尚未部署、没有 ngrok 域名,生成模板默认应关闭统一登录,继续用真实 Make 后端接口:

const auth = createMakeAppAuth({
  gatewayBaseUrl: import.meta.env.VITE_MAKE_GATEWAY_BASE_URL || '/api/make',
  unifiedLogin: false,
  accessToken: import.meta.env.VITE_MAKE_ACCESS_TOKEN
});

const boot = await auth.init({ redirect: false });

这种模式只用于本地调试。缺少 token 时不要跳 Org 登录页,应提示用户配置 VITE_MAKE_ACCESS_TOKENVITE_MAKE_TOKEN。只有显式配置 VITE_MAKE_AUTH_MODE=unified 或等价开关时才启用统一登录。

安全边界:

  • gatewayBaseUrl 是 Make API 网关入口,不是统一登录地址;已发布 App 默认使用同源 /api/make
  • 业务代码应传相对路径,例如 /data/v1/record,SDK 会拼到 gatewayBaseUrl 下。
  • 如果传入绝对 URL,SDK 只允许它落在 gatewayBaseUrl 的同一 origin 和路径作用域内;否则拒绝请求,避免 token 模式下把 Authorization 发到外部域名。

列表没有过滤条件时不要传 filter 字段,尤其不要传 filter: []。需要过滤时再按业务条件追加:

const body = {
  app: 'expense',
  entity: 'reimbursement',
  fields: [],
  pagination: { page: 1, size: 10 }
};

if (keyword) {
  body.filter = [{ title: { contains: keyword } }];
}

await auth.api.post('/data/v1/record', body, {
  headers: {
    'X-Make-Target': 'MakeService.ListResources'
  }
});
await auth.api.get('/meta/v1/schema?app=expense');
await auth.api.post('/data/v1/record', payload, {
  headers: {
    'X-Make-Target': 'MakeService.CreateRecord',
    'X-Trace-Id': traceId
  }
});
await auth.api.put('/data/v1/record/123', payload);
await auth.api.delete('/data/v1/record/123');

底层仍保留 auth.fetch(path, init) / auth.request(path, init),用于少量需要完整控制 RequestInit 的场景。Vibe 生成代码默认应使用 auth.api,不要直接调用原生 window.fetch 访问 Make 后端。

退出

await auth.logout();

默认语义是“退出账号”,不是只退出当前 App。SDK 会:

  1. POST /api/make/auth/logout?return_url=...
  2. make-gateway 在后端尽力调用 Org /api/account/logout 清理当前账号 token。
  3. 不管 Org 清理是否成功,make-gateway 都会清理当前 App 会话。
  4. make-gateway 返回受校验的 redirectUri
  5. SDK 只按 redirectUri 跳转,不拼接账号中心或 Org URL,也不再兼容旧 orgSsoLogoutUrl
  6. 页面再次启动时继续走 /auth/current-context,如果 Org 账号 token 已失效,会进入 Org 统一登录页。

默认 return_url 是当前域名根路径 /。如果 App 需要回到指定入口,可以显式传入:

await auth.logout({
  returnUrl: window.location.origin + '/'
});

注意:App 前端不自行拼 Org logout URL,也不处理 Org token;只调用 auth.logout()。退出后的跳转地址由 make-gateway 返回。

API

const auth = createMakeAppAuth({
  gatewayBaseUrl: '/api/make',
  currentContextPath: '/auth/current-context',
  runtimeViewPath: '/auth/runtime-view',
  exchangePath: '/oauth/token/exchange',
  logoutPath: '/auth/logout',
  apiAuthRedirect: true,
  accessToken: undefined,
  tokenProvider: undefined,
  credentialsProfile: 'default',
  credentialsPath: undefined
});

方法:

  • init(options)
  • login(options)
  • loginGuard(options)
  • getCurrentContext(options)
  • getRuntimeView(options)
  • handleOAuthCallback(options)
  • exchangeCode({ code, state })
  • logout(options)
  • api.request(path, init)
  • api.get(path, init)
  • api.post(path, body, init)
  • api.put(path, body, init)
  • api.patch(path, body, init)
  • api.delete(path, init)
  • fetch(path, init)
  • request(path, init)
  • apiUrl(path)

错误类型:

  • MakeAppAuthError
  • MakeAppUnauthorizedError
  • MakeAppForbiddenError

调试 demo 同步

调试页是纯静态部署,为了部署时不依赖跨目录 import,会保留一份 vendored SDK 文件:

demo/vibe-auth-debug-app/sdk/make-app-auth.mjs

修改 SDK 后执行:

pnpm --dir make-app-auth-sdk sync:demo

接入 make-platform-skills

如果希望后续 Vibe App 由 Codex / make-platform-skills 生成时自动使用统一登录,需要把 SDK 接入规则固化到 makeui skill,而不是只写在单个 App 里。

推荐落地方式:

  1. make-platform-skills/skills/makeui/SKILL.md 增加 Make App 认证基线。
  2. make-platform-skills/skills/makeui/references/auth-sdk-integration.md 沉淀详细规则。
  3. 将同一份 skill 同步到本机已安装目录 /Users/apple/.codex/skills/makeui
  4. 后续生成 Vibe App 时触发 makeui skill,它会默认生成 @qfeius/make-app-auth 接入代码。

makeui 中建议固化的最小规则:

When generating a Make App frontend, wire authentication through `@qfeius/make-app-auth` by default.

Generated Vibe Apps should:
- depend on `@qfeius/make-app-auth`
- expose an explicit auth mode config: default local token, explicit unified login, or mock preview
- call `auth.init({ redirect: true })` in unified mode so unauthenticated users go to the Org login page
- not render an App-owned login page, login transition page, or signed-out completion page for unified login
- show a simple expired-login prompt when `auth.init()` returns `reason="state_expired"` or `reason="challenge_expired"`
- call `auth.login({ redirect: true })` only for expired-session re-login actions
- use `auth.api` for `/api/make/**` business requests
- call `await auth.logout()` for logout
- use `createMakeAppAuth({ unifiedLogin: false, accessToken })` when local token mode is selected

Generated Vibe Apps must not:
- read or persist Org tokens, `zs_session`, or `make_app_session`
- construct Org OAuth URLs, `redirect_uri`, `state`, or `code_challenge`
- handle Org OAuth `code`
- call Make backend with raw `window.fetch('/api/make/...')`
- monkey patch `window.fetch`
- send `filter: []` for unfiltered list requests

可直接复制本仓库的指导文档作为 skill reference:

mkdir -p /Users/apple/code/make/make-platform-skills/skills/makeui/references
cp docs/skill-integration.md \
  /Users/apple/code/make/make-platform-skills/skills/makeui/references/auth-sdk-integration.md

同步到当前 Codex 已安装 skill:

mkdir -p /Users/apple/.codex/skills/makeui/references
cp /Users/apple/code/make/make-platform-skills/skills/makeui/SKILL.md \
  /Users/apple/.codex/skills/makeui/SKILL.md
cp /Users/apple/code/make/make-platform-skills/skills/makeui/references/auth-sdk-integration.md \
  /Users/apple/.codex/skills/makeui/references/auth-sdk-integration.md

接入后建议检查:

rg -n "auth\\.fetch|auth\\.request\\(\\)|window\\.fetch\\('/api/make|filter:\\s*\\[\\]" \
  /Users/apple/code/make/make-platform-skills/skills/makeui \
  /Users/apple/.codex/skills/makeui

这些关键词只应该出现在“禁止生成”的说明里,不应该出现在推荐代码示例里。

Vibe App 模板

SDK 内置一个最小模板:

make-app-auth-sdk/templates/vibe-app

模板约定:

  • unified 模式启动时调用 auth.init({ redirect: true }),未登录直接跳 Org 登录页。
  • 会话过期后的重新登录只调用 auth.login({ redirect: true });不要生成退出完成页。
  • 业务请求只通过 auth.api 访问 /api/make/**
  • 不在前端拼 Org OAuth URL,不处理 redirect_uricode_challengecode/state exchange
  • App 发布后必须放在平台统一管理的稳定域名下,且该域名能同源代理 /api/make/** 到 make-gateway。

生成 App 推荐直接使用公共 npm 依赖:

{
  "dependencies": {
    "@qfeius/make-app-auth": "^0.1.2"
  }
}

发布

发布前检查:

pnpm --dir make-app-auth-sdk check

公共 npm 发布方式:

pnpm --dir make-app-auth-sdk publish --registry=https://registry.npmjs.org/ --access public

测试

pnpm --dir make-app-auth-sdk test
pnpm --dir make-app-auth-sdk check