Northlight

Signing people in

The OAuth client that connects a person to the app, where connections are stored, the client on a stored connection, and how a refused connection is handled.

Exports of @north-light/sdk, read from the TypeScript compiler at build time. Types re-exported from @north-light/api are documented with that package.

AppClient

type declared in client.ts

What an app reaches on a person's runtime (the app listener): Crouter without the owner-daemon namespaces, files.download only, and profiles.list only. Crouter is assignable to it, so a function that takes AppClient takes either.

Prop

Type

AuthorizationRefusal

interface declared in oauth/refusal.ts

A sign-in the directory refused before issuing a code, read from the redirect back to the app (authorizationRefusalOf).

Prop

Type

authorizationRefusalOf

function declared in oauth/refusal.ts

The AuthorizationRefusal a sign-in redirect carries when the directory refused the person (error=access_denied with a reason the SDK knows), else null. Pass the callback's query: a URL, a URL or query string, a URLSearchParams, or a parsed query object. A person who pressed Cancel (access_denied without a known reason) and any other error answer null; handle those yourself. There is no grant to refresh, so no onRefusal runs.

(callback: CallbackQuery) => AuthorizationRefusal | null

AuthorizeNonce

type declared in oauth/index.ts

authorizeUrl's nonce: string when the scopes are known to include openid, undefined when known not to, else either.

string extends S[number] ? string | undefined : "openid" extends S[number] ? string : undefined

ConnectedCrouter

class declared in oauth/index.ts

A runtime client on one person's stored connection (oauth.client(userId)): an AppClient that refreshes its token through the OAuth2Client's store, plus whose connection it is and the runtime it calls. It offers only what the person's app listener serves. The owner-daemon namespaces (nodes, crons, canvas, …) are absent from its type and throw CrouterError if reached anyway; files is download only and profiles is list only. request still sends any route.

Prop

Type

Connection

interface declared in oauth/index.ts

Prop

Type

ConnectionStore

interface declared in oauth/index.ts

Prop

Type

DEFAULT_DIRECTORY_TIMEOUT_MS

variable declared in oauth/index.ts

The default deadline of one directory operation (OAuth2Options.timeoutMs): a discovery read is forgotten when it passes.

Prop

Type

generateKeyPair

function declared in oauth/keygen.ts

Make an app signing key and the public JWK to register in the directory.

() => Promise<{ privateJwk: JWK; publicJwk: JWK; kid: string; }>

Identity

interface declared in oauth/index.ts

A person's Northlight identity from a sign-in-only (openid, openid email, openid profile, or openid email profile) request, read from an ID token the SDK verified: ES256 signature against the directory's JWKS, iss, aud = the client id, exp, and the nonce from authorizeUrl. It is not a connection: it holds no runtime URL, refresh token, or grant, and nothing can be called on the person's runtime with it.

Prop

Type

MemoryConnectionStore

class declared in oauth/index.ts

A connection store for one process (local development and tests): its lock does not reach other processes.

Prop

Type

OAuth2Client

class declared in oauth/index.ts

Prop

Type

OAuth2Options

interface declared in oauth/index.ts

Prop

Type

OwnerOnly

type declared in client.ts

The namespaces of Crouter that only the owner's own daemon serves. A person's app listener answers them 404 unknown operation.

"auth" | "bash" | "canvas" | "crons" | "customObjects" | "human" | "models" | "nodes" | "structuredRequests" | "system"

parsePrivateJwk

function declared in oauth/keygen.ts

Check that value (a JWK object or its JSON text) is a private signing key with a kid, and return it as OAuth2Options.privateKey takes it. source names where it came from in the error, e.g. a file path.

(value: string | JWK, source?: string) => JWK & { d: string; kid: string; }

privateKeyFromFile

function declared in oauth/keygen.ts

Read a private JWK file, such as the one crouter-sdk keygen writes, and check it as parsePrivateJwk does. Node only.

(path: string) => Promise<JWK & { d: string; kid: string; }>

profileFromClaims

function declared in oauth/index.ts

The profile claims a verified ID token carries, each only when present: use it on Connection.idToken after verifyIdToken for a sign-in that requested runtime scopes (exchangeCode), as exchangeIdentity does for a sign-in-only one.

(claims: IdTokenClaims) => Pick<Identity, 'name' | 'givenName' | 'familyName' | 'picture'>

RefreshFailure

interface declared in oauth/index.ts

One connection refreshIdleConnections could not refresh and that is still stored: an error other than a refusal, or a refusal whose onRefusal threw (then refusalOf(error) is set and error.cause is what it threw).

Prop

Type

Refusal

interface declared in oauth/refusal.ts

A connection the directory refused to refresh: passed to OAuth2Options.onRefusal, and read from the refused call's error with refusalOf(error). The SDK removes the stored connection once the handler resolves.

Prop

Type

RefusalKind

type declared in oauth/refusal.ts

What a refused refresh means for the app's data: - removed (grant_removed): the person removed the app or deleted their account. The runtime has deleted the app's runs; delete what the app stores for them. - paused (grant_suspended): the grant is suspended or expired. Nothing was deleted; keep the person's data and show the app paused until they sign in again. - paused also covers app_in_testing: the app is still in testing and the person is not its admin or a named tester (they were removed as a tester, or their email or phone stopped matching). The grant is revoked, not removed, and the person's data is kept; they get access back when the developer adds them again and they sign in again. - reconnect (refresh_token_expired, refresh_token_reused, or grant_revoked with no reason given): the grant still exists. Nothing was deleted; ask them to sign in again.

"paused" | "reconnect" | "removed"

refusalOf

function declared in oauth/refusal.ts

The Refusal a call failed with when the directory refused its connection's refresh, else null. Read it to answer one request (show "sign in again"); act on the connection itself in OAuth2Options.onRefusal, which the SDK has already run. Only an error raised by OAuth2Client refreshing a stored connection carries one; a 429, cap_exhausted, scope_missing, or a runtime-origin grant_revoked does not.

(error: unknown) => Refusal | null

On this page