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

@qentrah/auth-sdk

v0.3.4

Published

Batteries-included Qentrah partner integration SDK for developers building OAuth, webhooks, resource calls, and consoles.

Downloads

352

Readme

@qentrah/auth-sdk

Documentation · Install guide

Batteries-included Qentrah partner integration SDK for developers building OAuth, webhooks, resource calls, and consoles.

These guides describe the published 0.3.2 package. The examples use the APIs and files in that release; beta packages should be kept on matching versions.

Documentation

Install and verify

Before you start

The package does not declare an engine requirement. Use a maintained Node.js release appropriate to your host application.

Use a project with a package.json. Check the runtime and package manager:

node --version
npm --version

Install the documented version

npm install @qentrah/[email protected]

Confirm the installation

npm ls @qentrah/auth-sdk

The output should show @qentrah/[email protected]. Commit the lockfile so another developer installs the same dependency tree.

Environment Variables

Use your own secret manager, hosting provider settings, or deployment environment.

QENTRAH_WORKSPACE_BASE_URL=https://app.qentrah.com
QENTRAH_PARTNER_CLIENT_ID=<your-partner-client-id>
QENTRAH_PARTNER_CLIENT_SECRET=<optional-confidential-client-secret>
QENTRAH_PARTNER_REDIRECT_URI=https://your-app.example.com/api/qentrah/oauth/callback
QENTRAH_PARTNER_SCOPES="organization:read client:read"
QENTRAH_WEBHOOK_SIGNING_SECRET=<your-webhook-signing-secret>

QENTRAH_PARTNER_CLIENT_SECRET is only needed for confidential client setups. Never place it in browser-visible configuration.

You can normalize the public OAuth settings with:

import { qentrahPartnerAuthorityFromEnv } from "@qentrah/auth-sdk/partner";

const authority = qentrahPartnerAuthorityFromEnv({
  QENTRAH_WORKSPACE_BASE_URL: process.env.QENTRAH_WORKSPACE_BASE_URL,
  QENTRAH_PARTNER_CLIENT_ID: process.env.QENTRAH_PARTNER_CLIENT_ID,
  QENTRAH_PARTNER_REDIRECT_URI: process.env.QENTRAH_PARTNER_REDIRECT_URI,
  QENTRAH_PARTNER_SCOPES: process.env.QENTRAH_PARTNER_SCOPES,
});

Browser Connect Button

<button id="qentrah-authorize">Authorize with Qentrah</button>
import { mountQentrahAuthorizeButton } from "@qentrah/auth-sdk/partner/browser";

mountQentrahAuthorizeButton({
  buttonId: "qentrah-authorize",
  startUrl: "/api/qentrah/oauth/start",
  label: "Authorize with Qentrah",
  disabledLabel: "Opening...",
  onError(error) {
    reportConnectionError(error);
  },
});

The button should point at a backend route in your app. It should not receive tokens or secrets.

Expected result

The connect button opens your backend start route. It cannot complete authorization until you implement server-side state and token storage and register the callback URI.

Connect and refresh OAuth

Run this integration code on the server unless the example explicitly mounts a browser button. tokenVault, savePendingOAuthState, loadQentrahSession, and event callbacks are application integration points, not exports supplied by the SDK. Implement them with your storage and user-session model.

OAuth Routes

The Next.js helper is optional. Use it if your app uses Next route handlers.

// app/api/qentrah/oauth/config.ts
import { createQentrahPartnerAuthHandlers } from "@qentrah/auth-sdk/partner/next";

export const qentrahAuth = createQentrahPartnerAuthHandlers({
  workspaceBaseUrl: process.env.QENTRAH_WORKSPACE_BASE_URL!,
  clientId: process.env.QENTRAH_PARTNER_CLIENT_ID!,
  clientSecret: process.env.QENTRAH_PARTNER_CLIENT_SECRET,
  redirectUri: process.env.QENTRAH_PARTNER_REDIRECT_URI!,
  scopes: ["organization:read", "client:read"],

  sessionStore: {
    async savePendingAuthorization({ pending, request }) {
      await savePendingOAuthState(request, pending);
    },
    async loadPendingAuthorization({ state, request }) {
      return loadPendingOAuthState(request, state);
    },
    async clearPendingAuthorization({ state, request }) {
      await clearPendingOAuthState(request, state);
    },
  },

  tokenStore: {
    async saveTokens({ organizationId, tokenSet, scopes }) {
      await tokenVault.save({
        provider: "qentrah",
        organizationId,
        scopes,
        tokenSet,
      });
    },
  },

  afterSuccessRedirect: "/settings/integrations/qentrah?connected=1",
  afterErrorRedirect: "/settings/integrations/qentrah?error=1",
});
// app/api/qentrah/oauth/start/route.ts
import { qentrahAuth } from "../config";

export const GET = qentrahAuth.start;
// app/api/qentrah/oauth/callback/route.ts
import { qentrahAuth } from "../config";

export const GET = qentrahAuth.callback;

For other backend frameworks, use the lower-level helpers from @qentrah/auth-sdk/partner and wire the generated redirect URL, pending state storage, callback validation, and token storage into your own routes.

Refresh Tokens

Refresh from server code, then save the returned token set back to your secure storage.

import { refreshQentrahPartnerAccessToken } from "@qentrah/auth-sdk/partner";

const tokenSet = await refreshQentrahPartnerAccessToken({
  workspaceBaseUrl: process.env.QENTRAH_WORKSPACE_BASE_URL!,
  clientId: process.env.QENTRAH_PARTNER_CLIENT_ID!,
  clientSecret: process.env.QENTRAH_PARTNER_CLIENT_SECRET,
  refreshToken: savedRefreshToken,
});

await tokenVault.save({ provider: "qentrah", tokenSet });

Call partner resources

Run this integration code on the server unless the example explicitly mounts a browser button. tokenVault, savePendingOAuthState, loadQentrahSession, and event callbacks are application integration points, not exports supplied by the SDK. Implement them with your storage and user-session model.

Service-App Client

Use the service client from server code after your app has a saved access token.

import { createQentrahServiceAppClient } from "@qentrah/auth-sdk/partner/service-app";

const qentrah = createQentrahServiceAppClient({
  workspaceBaseUrl: process.env.QENTRAH_WORKSPACE_BASE_URL!,
  accessToken: savedAccessToken,
});

const organization = await qentrah.me();

const clients = await qentrah.listClients({
  organizationId,
  options: {
    limit: 25,
    search: "Acme",
    status: "active",
  },
});

const createdClient = await qentrah.createClient({
  organizationId,
  input: {
    name: "Acme Buyer",
    email: "[email protected]",
  },
  idempotencyKey: createIdempotencyKey(),
});

await qentrah.updateClient({
  organizationId,
  clientId: createdClient.id,
  input: { name: "Acme Buyer Updated" },
});

await qentrah.deleteClient({
  organizationId,
  clientId: createdClient.id,
});

Read helpers include:

  • me
  • listClients
  • listProperties
  • listProjects
  • listTasks
  • listCalendar
  • listMedia
  • listWebhooks

Common options include limit, cursor, search, type, status, startAt, endAt, indexStart, and indexEnd. Media also supports resourceType and resourceId.

The older read, write, and sendWebhook helpers remain available for existing integrations.

Verify webhooks

Run this integration code on the server unless the example explicitly mounts a browser button. tokenVault, savePendingOAuthState, loadQentrahSession, and event callbacks are application integration points, not exports supplied by the SDK. Implement them with your storage and user-session model.

Webhook Verification

Use webhook helpers from server code. The signing secret must remain server-side.

// app/api/qentrah/webhooks/route.ts
import { createQentrahWebhookHandler } from "@qentrah/auth-sdk/partner/webhooks";

export const runtime = "nodejs";

export const POST = createQentrahWebhookHandler({
  signingSecret: process.env.QENTRAH_WEBHOOK_SIGNING_SECRET!,
  handlers: {
    async "client.created"(event) {
      await syncClientCreated(event.data);
    },
    async "client.updated"(event) {
      await syncClientUpdated(event.data);
    },
    async "client.deleted"(event) {
      await syncClientDeleted(event.data);
    },
  },
  async onUnhandledEvent(event) {
    await recordUnhandledEvent(event.type);
  },
});

Verify against the original request body before parsing JSON. The helper does that for standard Request objects.

Build an integration console

Run this integration code on the server unless the example explicitly mounts a browser button. tokenVault, savePendingOAuthState, loadQentrahSession, and event callbacks are application integration points, not exports supplied by the SDK. Implement them with your storage and user-session model.

Headless Integration Harness

The harness gives you reusable data models for a developer console without forcing a React component or a specific app layout.

import {
  createQentrahPartnerConsoleService,
  qentrahPartnerSections,
} from "@qentrah/auth-sdk/partner/harness";

const consoleService = createQentrahPartnerConsoleService({
  workspaceBaseUrl: process.env.QENTRAH_WORKSPACE_BASE_URL!,
  redirectUri: process.env.QENTRAH_PARTNER_REDIRECT_URI!,
  requestedScopes: ["organization:read", "client:read", "client:create"],
  session: await loadQentrahSession(userId),
});

const sections = consoleService.sections();
const lifecycle = consoleService.lifecycle();
const credentialSnapshot = consoleService.credentials();
const clientsQuery = consoleService.searchParams("clients", {
  limit: 25,
  search: "Acme",
  status: "active",
});

The harness can:

  • Return the available console sections and the scopes each section needs.
  • Detect missing scopes and reauthorization needs.
  • Build OAuth lifecycle metadata for docs or UI.
  • Build query parameters for list filters.
  • Convert API responses into compact render rows.
  • Normalize operation results for Test Results views.
  • Sanitize nested payloads before rendering them.

Example rendering flow:

const result = await consoleService.runResourceOperation({
  sectionId: "clients",
  operation: "read",
  resource: "client",
  options: { limit: 25, search: "Acme" },
});

const rows = consoleService.renderRows("clients", result.responseSummary);
const safeResult = consoleService.result({
  sectionId: "clients",
  operation: "read",
  method: "GET",
  path: "/api/qentrah/clients",
  status: result.status,
  response: result.responseSummary,
  error: result.error,
});

Render rows, sections, lifecycle, credentialSnapshot, and safeResult with your own UI framework.

WordPress And Server-Backed Apps

For WordPress or PHP-backed products, keep the same separation of responsibilities:

  • Enqueue the browser button script in the admin screen or integration settings page.
  • Point the button at a server route that starts OAuth.
  • Store pending OAuth state in a server-side session or database table.
  • Complete the callback on the server and save token data in encrypted storage.
  • Proxy Qentrah resource calls through server endpoints.
  • Render only sanitized connection status, section readiness, request summaries, and result summaries in the admin UI.

If your WordPress plugin uses a Node service or build step, you can use this package directly in that server layer. If your backend is pure PHP, mirror the same OAuth, webhook, and storage contract server-side, and use the browser bundle only for the connect button.

API and exports

Package identity

| Field | Value | | --- | --- | | Package | @qentrah/auth-sdk | | Version inspected | 0.3.2 | | License | UNLICENSED | | Module type | module |

Public import paths

| Import path | Published target | | --- | --- | | @qentrah/auth-sdk | ./dist/index.d.ts | | @qentrah/auth-sdk/errors | ./dist/errors/index.d.ts | | @qentrah/auth-sdk/partner | ./dist/partner/index.d.ts | | @qentrah/auth-sdk/partner/browser | ./dist/partner/browser/index.d.ts | | @qentrah/auth-sdk/partner/next | ./dist/partner/next/index.d.ts | | @qentrah/auth-sdk/partner/service-app | ./dist/partner/service-app/index.d.ts | | @qentrah/auth-sdk/partner/harness | ./dist/partner/harness/index.d.ts | | @qentrah/auth-sdk/partner/webhooks | ./dist/partner/webhooks/index.d.ts | | @qentrah/auth-sdk/qentrah-auth.js | ./dist/qentrah-auth.js | | @qentrah/auth-sdk/package.json | ./package.json |

Exports

import {
  buildQentrahPartnerAuthorizeUrl,
  exchangeQentrahPartnerAuthorizationCode,
  refreshQentrahPartnerAccessToken,
  qentrahPartnerAuthorityFromEnv,
} from "@qentrah/auth-sdk/partner";

import { mountQentrahAuthorizeButton } from "@qentrah/auth-sdk/partner/browser";
import { createQentrahPartnerAuthHandlers } from "@qentrah/auth-sdk/partner/next";
import { createQentrahServiceAppClient } from "@qentrah/auth-sdk/partner/service-app";
import { createQentrahWebhookHandler, verifyQentrahWebhook } from "@qentrah/auth-sdk/partner/webhooks";
import {
  createQentrahPartnerConsoleService,
  qentrahPartnerSections,
  sanitizeQentrahPartnerPayload,
} from "@qentrah/auth-sdk/partner/harness";

The browser bundle is also available as:

<script src="/qentrah-auth.js"></script>

It exposes:

window.QentrahAuth.mountAuthorizeButton(...)

Inspect the original release

Open the versioned npm page or download its published archive. The archive includes the actual executable files and declarations used to write these guides.

Troubleshooting

Check the installed version

npm ls @qentrah/auth-sdk

Compare the installed version with the version noted in this guide. Inspect your lockfile before changing dependencies; prerelease behavior may differ between versions.

Import or module errors

Use only public import paths listed in API and exports. Avoid importing guessed paths inside dist. ESM-only packages require an ESM-aware application. Install declared peer dependencies in the consuming application.

Error Handling

SDK errors are stable enough to branch on:

  • CONFIGURATION_ERROR
  • AUTHORIZATION_DENIED
  • INVALID_STATE
  • TOKEN_EXCHANGE_FAILED
  • ORGANIZATION_AUTHORIZATION_MISSING
  • MISSING_RAW_BODY
  • STALE_TIMESTAMP
  • INVALID_SIGNATURE
  • UNSUPPORTED_RUNTIME
import { isQentrahPartnerAuthError } from "@qentrah/auth-sdk/partner";

try {
  await connectQentrah();
} catch (error) {
  if (isQentrahPartnerAuthError(error)) {
    await recordIntegrationIssue({
      code: error.code,
      message: error.message,
    });
  }
}

Security Rules

Keep sensitive values out of browser code, public logs, screenshots, client bundles, docs, and version control.

  • Browser code should only redirect to your backend start route.
  • Exchange authorization codes on the server.
  • Store access tokens, refresh tokens, client secrets, webhook signing secrets, and authorization codes in your own secure server storage.
  • Verify webhook signatures before trusting event data.
  • Render only sanitized credential and result snapshots in admin UI.
  • Use placeholders in examples, docs, and tests.

Callback failures

For INVALID_STATE, check that the same user session loads the saved pending state and that state is cleared after use. For token exchange failures, check the registered redirect URI, client configuration, and authority URL. Store refreshed tokens atomically and never send the stored token set to a browser.

Release documentation

Documentation checked against the previously published package artifact. This documentation-only release preserves executable files and dependencies.