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

@incorta/auth

v1.9.0

Published

Authenticate Incorta users in any Node.js app — OAuth 2.0/OIDC against Incorta's built-in authorization server, with a React provider and Express/TanStack Start integrations.

Downloads

1,452

Readme

@incorta/auth

Authenticate Incorta users in any Node.js app via Incorta's built-in OAuth 2.0/OIDC authorization server. See the repository root README for the full guide; this is the API surface.

To read Incorta with the session this package holds — schemas, tables, columns, rows, all filtered to the signed-in user — add @incorta/sdk, released from this repository at the same version.

Entry points

| Import | What's in it | | ----------------------- | ------------------------------------------------------------------- | | @incorta/auth | createIncortaAuth, registerClient, getClient, updateClientRedirectUris, deleteClient, types (IncortaUser, AuthSession, …) | | @incorta/auth/react | IncortaAuthProvider, useAuth, useUser, SignedIn, SignedOut, Protect, RedirectToLogin | | @incorta/auth/express | incortaAuth(auth) middleware, requireAuth(auth, options?) | | @incorta/auth/node | toNodeHandler(auth), toWebRequest, sendWebResponse, getNodeSession |

createIncortaAuth(config?)

Returns { handler, getSession, config }:

  • handler(request: Request): Promise<Response> — serves, under config.basePath (default /auth):
    • GET /login?redirect_to= — 302 into the Incorta authorize flow (or straight back when already signed in), with a PKCE S256 challenge. Sets a sealed state+nonce+verifier cookie (10 min).
    • GET /callback — validates state, exchanges the code with the PKCE verifier (as a public client — client_id in the body — or with client_secret_basic when a secret is configured), verifies the ID token against the tenant JWKS (issuer, audience, nonce), seals the session cookie, 302 to the original page. Failures 302 to {redirect_to}?incorta_auth_error={code}.
    • GET /session — { user, session } or { user: null }. Refreshes the access token (rotating refresh token) when <60s from expiry; slides the session cookie past its half-life.
    • GET|POST /logout — clears the session cookie (GET redirects: to redirect_to when given, else to /signed-out).
    • GET /signed-out — ungated "you're signed out" page with a sign-in link; the react signOut() default destination. Landing anywhere gated would silently re-login via SSO while the Incorta session lives.
    • GET /token — the raw Incorta access token; only with exposeAccessToken: true, otherwise 404.
  • getSession(request): Promise<AuthSession | null> — read-only session lookup for server code (user, accessToken, accessTokenExpiresAt, expiresAt).

Config falls back to INCORTA_URL, INCORTA_TENANT, INCORTA_CLIENT_ID, INCORTA_AUTH_SECRET, INCORTA_APP_URL, INCORTA_CLIENT_SECRET (optional — only a confidential client has one; Incorta registers apps as public clients), and INCORTA_INTERNAL_URL (split horizon: server-side discovery/token/JWKS calls use it when the public incortaUrl is not routable from the app — e.g. http://host.docker.internal:8080/incorta from a local container; the authorize redirect and issuer validation stay on the public URL).

App access policy (appAccess / INCORTA_APP_ACCESS)

Who may use the app, enforced by the whole-app gate:

  • public — anyone with the URL, signed in or not. The gate is inert for app routes; the auth routes stay mounted, so signing in remains possible and sessions become optional (handle session == null).
  • authenticated (default) — any signed-in Incorta user. Exactly the pre-policy behavior, and what an absent/unknown INCORTA_APP_ACCESS means (unknown values warn and fall back here — never to public).
  • catalog — signed in AND at least VIEW access to this app in the Incorta catalog. The SDK asks GET {incortaUrl}/apps-catalog/check with the session's own access token; Incorta resolves which app the token belongs to from the OAuth client registration's (incorta-app:<id>) name suffix (written once, server-side, at registration), so the endpoint can only ever answer about this app. Verdicts (allow and deny) are cached 30s per user; apps not registered in the catalog stay open to authenticated users (legacy-open). When Incorta cannot answer, the gate fails CLOSED with a distinct 503 "temporarily unavailable" page (failures are not cached).

Enforcement surfaces:

  • auth.gate(request): Promise<Response | null> — the whole-app gate: serve the Response when non-null (auth routes, login redirects, the 403 access-denied page — which names the signed-in user and offers a switch-account logout — or the 503 page), continue to your app on null.
  • @incorta/auth/express: appGate(auth) middleware is auth.gate for Express/Connect. requireAuth(auth) always demands a session regardless of policy (an explicit route guard is the author's promise), and under catalog additionally requires VIEW, attaching the verdict as req.incortaAuth.appAccess.
  • auth.getAppAccess(session): Promise<AppAccess> — the cached verdict (registered, access bitmask, canView, canEdit, allowed) for permission-aware UX in any mode.

GET {basePath}/refresh?redirect_to= supports the catalog gate: it refreshes an expired access token through a browser round trip (persisting the rotated refresh-token cookie) and bounces back — the gate sends navigations there instead of calling Incorta with a token it knows is expired.

Session model

The cookie is an encrypted JWT (JWE dir/A256GCM, key derived from secret), HttpOnly, SameSite=Lax, Secure on HTTPS. Payload: verified user claims (sub, name, email, roles, tenant) + the Incorta access/refresh tokens. Nothing is stored server-side.

Embedded (cross-site iframe) mode: when the app runs inside an iframe on a DIFFERENT site, Lax cookies are never sent — the login flow loops forever. Set cookies: { sameSite: "none", partitioned: true } (or env INCORTA_COOKIE_SAMESITE=none + INCORTA_COOKIE_PARTITIONED=1): the auth cookies become SameSite=None; Secure; Partitioned (CHIPS), which modern Chrome allows in third-party iframes with a per-embedder cookie jar. none forces Secure (accepted on trustworthy plain-http origins like *.localhost); top-level usage keeps working with the same setting.

CLI

incorta-auth register --url http://localhost:8080/incorta --tenant demo \
  --name "My App" --redirect https://myapp.example.com/auth/callback [--json]

incorta-auth show --url ... --tenant ... --client <id> --rat <token> [--json]

incorta-auth update-redirects --url ... --tenant ... --client <id> --rat <token> \
  --redirect <url> [--redirect ...] [--replace] [--json]

incorta-auth delete --url ... --tenant ... --client <id> --rat <token>

register creates the OAuth client via RFC 7591 dynamic registration and prints the .env entries (keep the registration access token). show and update-redirects manage the registered client's allowed callback URLs — adding by default, replacing the whole set with --replace. delete removes the registration (new logins stop immediately; issued sessions live until they expire).

Testing

pnpm test runs the suite against an in-process replica of Incorta's OAuth endpoints (test/mock-incorta.ts) — full login/callback/refresh/logout flows over real HTTP sockets, no Incorta needed.