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

@zskj-idaas/sdk

v2.3.0

Published

IDaaS OIDC Client SDK for browser applications — supports Authorization Code Flow with PKCE, token management, and authenticated fetch.

Readme

@zskj-idaas/sdk

IDaaS OIDC Client SDK — 适用于浏览器应用的 OpenID Connect 客户端,支持 Authorization Code Flow with PKCE。

当前生产环境的 OIDC Issuer 是 https://account.genisomai.com。本文中的 IDaaS 端点均填写为完整生产地址。

特性

  • 零运行时依赖 — 轻量、无外部依赖
  • PKCE 支持 — 自动生成 code_verifier / code_challenge
  • 双模块输出 — 同时支持 ESM 和 CommonJS
  • TypeScript — 完整的类型定义
  • OIDC Discovery — 自动发现 OpenID 配置端点
  • Token 管理 — 自动存储、过期检测、静默刷新
  • 认证 Fetch — 内置带 Bearer Token 的 fetch 封装

安装

npm install @zskj-idaas/sdk
# 或
pnpm add @zskj-idaas/sdk
# 或
yarn add @zskj-idaas/sdk

快速开始

import { IdaasClient } from '@zskj-idaas/sdk';

const client = new IdaasClient({
  issuer: 'https://account.genisomai.com',
  clientId: 'my-app',
  redirectUri: `${window.location.origin}/callback`,
  postLogoutRedirectUri: window.location.origin,
  scope: 'openid profile email',
});

// 初始化(自动发现 OIDC 端点)
await client.init();

// 发起登录
await client.login();

clientId 必须替换为 IDaaS 管理员分配的 Public Client ID。当前 Origin、${window.location.origin}/callback 和 window.location.origin 必须分别登记到管理后台的 CORS Origins、Redirect URIs 和 Post Logout Redirect URIs。

生产端点

SDK 默认从 Discovery 自动读取标准 OIDC 端点。当前生产环境的完整地址如下:

| 用途 | 方法 | 完整地址 | | --- | --- | --- | | OIDC Discovery | GET | https://account.genisomai.com/.well-known/openid-configuration | | JWKS 公钥 | GET | https://account.genisomai.com/.well-known/jwks.json | | Authorization | GET | https://account.genisomai.com/oauth2/authorize | | Token | POST | https://account.genisomai.com/oauth2/token | | UserInfo | GET / POST | https://account.genisomai.com/oauth2/userinfo | | 企业资料(当前用户) | GET | https://account.genisomai.com/oauth2/enterprise-profile | | Business Token | POST | https://account.genisomai.com/oauth2/business-token | | Logout | GET | https://account.genisomai.com/oauth2/logout | | Revoke | POST | https://account.genisomai.com/oauth2/revoke | | Introspect | POST | https://account.genisomai.com/oauth2/introspect | | 清理 IDaaS Session | POST | https://account.genisomai.com/auth/logout | | Service Token Verify(仅业务后端) | POST | https://account.genisomai.com/api/service-auth/verify | | Authorization Evaluate(仅业务后端,以 my-app-service 为例) | POST | https://account.genisomai.com/api/service-auth/my-app-service/evaluate |

浏览器不能持有 ServiceCredential,因此不能直接调用最后两个服务端授权端点。my-app-service 是 Service Key 示例,实际接入时使用管理员分配的值。

API 参考

new IdaasClient(config)

创建 SDK 客户端实例。

interface IdaasConfig {
  issuer: string;               // OIDC 提供者地址
  clientId: string;             // 客户端 ID
  redirectUri: string;          // 登录回调地址
  postLogoutRedirectUri?: string; // 登出后跳转地址
  scope?: string;               // 请求的 scope(默认: 'openid profile email')
  autoDiscovery?: boolean;      // 是否自动发现端点(默认: true)
  storagePrefix?: string;       // 存储 key 前缀(默认: 'idaas')
}

该 SDK 仅用于浏览器 Public Client,始终使用 PKCE,不能配置或传输 Client Secret。

client.init(): Promise<AuthState>

初始化客户端,执行 OIDC Discovery 并返回当前认证状态。

client.login(extraParams?): Promise<void>

发起 OIDC 授权码登录流程,跳转到授权端点。

// 附加额外参数
await client.login({ prompt: 'login', login_hint: '[email protected]' });

client.handleCallback(callbackUrl?): Promise<TokenSet>

处理授权回调,用授权码交换 Token。

// 在回调页面调用
const tokens = await client.handleCallback();

client.getUserInfo(forceRefresh?): Promise<UserInfo | null>

获取当前用户信息。

管理员为 Client 开放 feishu_identity,并在登录时申请且经用户同意后,可返回以下可选字段:

  • feishu_union_id 与 feishu_tenant_key:必须成对完整,供同企业、同应用开发商范围内的跨飞书应用身份关联。
  • feishu_open_id:同一身份元数据中合法的 Open ID,供 IDaaS 所用飞书应用内关联,可与 primary_department_leaders[].feishu_open_id 对应。

未授权、身份歧义或 UnionID/企业标识缺失时不返回上述字段;仅 Open ID 缺失或非法时省略 feishu_open_id,保留原有完整关联键。不得从用户名推导 Open ID,也不得用它跨飞书应用匹配。身份字段不授予业务权限,不写入 ID Token 或业务 Token。

const user = await client.getUserInfo(true); // 强制重新获取,避免沿用先前缓存
const feishuOpenId = user?.feishu_open_id;
// 使用 feishuOpenId 进行同一飞书应用内关联;缺失时跳过关联,不记录身份值到日志。

client.getEnterpriseProfile(): Promise<EnterpriseProfile | null>

按当前应用获准且用户已同意的 Scope 获取当前用户的敏感企业资料。支持的独立 Scope 为 phone、employee_number 和 primary_department;对应字段不会进入 ID Token。

import { EnterpriseProfileError } from '@zskj-idaas/sdk';

try {
  const profile = await client.getEnterpriseProfile();
  console.log(profile?.employee_number);
  console.log(profile?.primary_department_path_name);
  console.log(profile?.primary_department_leaders);
} catch (error) {
  if (error instanceof EnterpriseProfileError && error.retryable) {
    // 提示用户稍后重试,不要把查询失败当成字段为空。
  }
}

primary_department_path 按一级部门到叶子部门排序,每项包含 id 和 name,不包含公司根节点;primary_department_path_name 是使用 / 连接的可展示路径。primary_department_leaders 返回主部门的主负责人和副负责人,每项包含 feishu_open_id、name、avatar_url 和 leader_type;leader_type 取值为 primary 或 deputy。负责人仍只需 primary_department scope,读取本人 feishu_open_id 则需 feishu_identity。兼容旧服务时,调用方可回退到 primary_department_name。

2.3.0 兼容升级

本版本为 EnterpriseDepartmentLeader 新增 feishu_open_id,并保留 open_id 等值兼容别名(标记为废弃);新服务端同时返回两个字段。为兼容旧服务和 2.x 调用方创建的对象,SDK 将新增字段声明为可选,可使用 leader.feishu_open_id ?? leader.open_id。UserInfo 新增可选的 feishu_open_id、feishu_union_id 和 feishu_tenant_key 类型。SDK 版本更新不等于服务端已部署或 npm 已发布。

client.getAccessToken(): Promise<string | null>

获取有效的 Access Token(过期时自动刷新)。

client.refreshToken(): Promise<TokenSet | null>

使用 Refresh Token 主动刷新 Token;刷新失败时清理本地登录态并返回 null。

client.getServiceToken(serviceKey): Promise<string | null>

调用 https://account.genisomai.com/oauth2/business-token 获取指定 Service 的业务 Token,并按 serviceKey 隔离缓存。

client.getIdToken(): string | null

获取 ID Token。

client.getAuthState(): AuthState

获取当前认证状态。

interface AuthState {
  isAuthenticated: boolean;
  user: UserInfo | null;
  accessToken: string | null;
  idToken: string | null;
  expiresAt: number | null;
}

client.isAuthenticated(): boolean

检查是否已认证。

client.logout(): Promise<void>

清理本地 Token,并跳转到 https://account.genisomai.com/oauth2/logout 执行 OIDC 登出。

client.logoutSession(options?): Promise<void>

清理本地 Token,并调用 https://account.genisomai.com/auth/logout 销毁 IDaaS Session;可通过 redirectTo 指定完成后的前端地址。

client.revokeToken(): Promise<void>

撤销 Refresh Token。

client.fetch(url, init?): Promise<Response>

带基础 IDaaS Access Token 的 fetch 封装,自动附加 Authorization 头。基础 Token 只允许用于 IDaaS UserInfo 和 Business Token 端点,不能用于业务 API;读取用户信息时优先使用 getUserInfo()。

const res = await client.fetch('https://account.genisomai.com/oauth2/userinfo');
const data = await res.json();

client.fetchService(serviceKey, url, init?): Promise<Response>

获取指定 Service 的业务 Token,并以 Bearer Token 调用业务 API。

const res = await client.fetchService('my-app-service', '/api/customers');
const data = await res.json();

完整示例

import { IdaasClient } from '@zskj-idaas/sdk';
import type { AuthState, UserInfo } from '@zskj-idaas/sdk';

const client = new IdaasClient({
  issuer: 'https://account.genisomai.com',
  clientId: 'my-app',
  redirectUri: `${window.location.origin}/callback`,
  postLogoutRedirectUri: window.location.origin,
});

// 应用启动时初始化
async function bootstrap() {
  const state: AuthState = await client.init();

  if (state.isAuthenticated) {
    const user: UserInfo | null = await client.getUserInfo();
    console.log('已登录:', user?.name);
  }
}

// 回调页面处理
async function handleCallback() {
  try {
    await client.handleCallback();
    window.location.href = '/';
  } catch (err) {
    console.error('登录失败:', err);
  }
}

// 调用受保护的 API
async function fetchData() {
  const res = await client.fetchService('my-app-service', '/api/data');
  return res.json();
}

导出内容

// 类
export { EnterpriseProfileError, IdaasClient } from './client';
export { TokenStorage } from './storage';

// 工具函数
export { createPKCE, generateState, generateNonce } from './crypto';

// 类型
export type { IdaasConfig, TokenSet, UserInfo, EnterpriseDepartmentPathItem, EnterpriseProfile, AuthState } from './types';

浏览器兼容性

需要支持 Web Crypto API 的现代浏览器:

  • Chrome 63+
  • Firefox 57+
  • Safari 11.1+
  • Edge 79+

License

MIT