Skip to content
Color theme

API: @loopstack/oauth

Classes

BuildOAuthUrlTool

Tool that builds an OAuth 2.0 authorization URL for a provider, including a CSRF state parameter.

import { BuildOAuthUrlTool } from '@loopstack/oauth';

Provided by: OAuthModule

export class BuildOAuthUrlTool extends BaseTool<BuildOAuthUrlArgs, object, BuildOAuthUrlResult> {
protected handle(args: BuildOAuthUrlArgs): Promise<ToolEnvelope<BuildOAuthUrlResult>>;
}

ExchangeOAuthTokenTool

Tool that exchanges an OAuth 2.0 authorization code for access and refresh tokens and stores them for the user.

import { ExchangeOAuthTokenTool } from '@loopstack/oauth';

Provided by: OAuthModule

export class ExchangeOAuthTokenTool extends BaseTool<ExchangeOAuthTokenArgs, object, ExchangeOAuthTokenResult> {
protected handle(args: ExchangeOAuthTokenArgs, ctx: RunContext): Promise<ToolEnvelope<ExchangeOAuthTokenResult>>;
}

OAuthCallbackController

Public OAuth callback endpoints that complete the authorization-code flow from code + state alone: the state token (unguessable, single-use, 10 minute TTL, re-validated by the workflow’s own expectedState check) resolves the pending OAuthWorkflow, whose exchangeToken transition is fired server-side as the user who started the flow.

Two entry points, same completion:

  • GET /api/v1/oauth/callback — a provider redirect target (*_OAUTH_REDIRECT_URI=<api>/api/v1/oauth/callback); renders a minimal “connected” page. Works without the Studio frontend — CLI-printed auth URLs and headless deployments complete here.
  • POST /api/v1/oauth/complete — JSON variant used by Studio’s callback page when it was opened without a popup opener (e.g. from a CLI link while the redirect URI still points at Studio).
import { OAuthCallbackController } from '@loopstack/oauth';

Provided by: OAuthModule

export class OAuthCallbackController {
constructor(sessions: OAuthSessionService, workflowRunner: WorkflowRunner);
complete(payload: CompleteOAuthPayload): Promise<{
ok: true;
provider: string;
}>;
callback(res: Response, code?: string, state?: string, error?: string, errorDescription?: string): Promise<void>;
}

OAuthModule

NestJS module that provides the provider-agnostic OAuth 2.0 framework — the OAuthProviderRegistry and OAuthTokenStore services, the build_oauth_url and exchange_oauth_token tools, and the generic OAuthWorkflow for the authorization code flow.

Registration:

  • OAuthModule — a bare import is enough. The module is @Global(), so a single import anywhere makes its services, tools, and workflow available application-wide via DI; no static configuration method exists.

Requires: at least one OAuth provider implementing OAuthProviderInterface must be registered for authentication to do anything useful — provider modules (e.g. @loopstack/google-workspace or @loopstack/github) self-register on init via OAuthProviderRegistry. Token persistence uses Redis (REDIS_HOST/REDIS_PORT/REDIS_PASSWORD) but is optional, falling back to in-memory storage when Redis is unavailable.

import { OAuthModule } from '@loopstack/oauth';
export class OAuthModule {}

OAuthPromptDocument

Document that renders the OAuth authorization prompt (provider, auth URL, and connection status) in Studio.

import { OAuthPromptDocument } from '@loopstack/oauth';
export class OAuthPromptDocument {
provider: string;
authUrl: string;
state: string;
status: 'pending' | 'success' | 'error';
message?: string;
}

OAuthSessionService

Service that registers pending OAuth flows by their CSRF state and hands them out exactly once (Redis-backed with in-memory fallback, 10 minute TTL) — the server-side state → workflow lookup behind the public OAuth callback.

import { OAuthSessionService } from '@loopstack/oauth';

Provided by: OAuthModule

export class OAuthSessionService implements OnModuleDestroy {
constructor();
onModuleDestroy(): void;
register(state: string, session: OAuthSession): Promise<void>;
consume(state: string): Promise<OAuthSession | undefined>;
}

OAuthTokenStore

Service that stores and retrieves per-user OAuth tokens (Redis-backed, with in-memory fallback) and transparently refreshes expired access tokens; inject it to read a valid access token for a provider.

import { OAuthTokenStore } from '@loopstack/oauth';

Provided by: OAuthModule

export class OAuthTokenStore implements OnModuleDestroy {
constructor();
onModuleDestroy(): void;
storeTokens(userId: string, providerId: string, tokens: StoredTokens): Promise<void>;
storeFromTokenSet(userId: string, providerId: string, tokenSet: OAuthTokenSet): Promise<void>;
getTokens(userId: string, providerId: string): Promise<StoredTokens | undefined>;
getValidAccessToken(userId: string, providerId: string): Promise<string | undefined>;
}

OAuthWorkflow

Workflow that runs the OAuth 2.0 authorization code flow for a provider: it builds the auth URL, prompts the user via an OAuthPromptDocument, and exchanges the returned code for stored tokens. Run it standalone to pre-authenticate or invoke it from another workflow when authentication is required.

import { OAuthWorkflow } from '@loopstack/oauth';

Provided by: OAuthModule

export class OAuthWorkflow extends BaseWorkflow<OAuthArgs> {
constructor(
buildOAuthUrl: BuildOAuthUrlTool,
exchangeOAuthToken: ExchangeOAuthTokenTool,
sessions: OAuthSessionService,
);
initiateOAuth(state: OAuthState, ctx: RunContext<OAuthArgs>): Promise<void>;
exchangeToken(
state: OAuthState,
input: TransitionInput<{
code: string;
state: string;
}>,
): Promise<void>;
}

Interfaces

BuildOAuthUrlResult

Result for BuildOAuthUrlTool.

import { BuildOAuthUrlResult } from '@loopstack/oauth';
export interface BuildOAuthUrlResult {
authUrl: string;
state: string;
}

OAuthProviderInterface

Contract that an OAuth 2.0 provider implements to plug into the OAuth framework; implement it to add a new provider.

import { OAuthProviderInterface } from '@loopstack/oauth';
export interface OAuthProviderInterface {
readonly providerId: string;
readonly defaultScopes: string[];
buildAuthUrl(scopes: string[], state: string): string;
exchangeCode(code: string): Promise<OAuthTokenSet>;
refreshToken(refreshToken: string): Promise<OAuthTokenSet>;
}

OAuthSession

Pending OAuth flow registered when the authorization URL is built — the lookup that lets the public callback complete the exchange from code + state alone, regardless of who opened the URL (Studio popup, CLI-printed link, plain browser).

import { OAuthSession } from '@loopstack/oauth';
export interface OAuthSession {
workflowId: string;
userId: string;
provider: string;
}

OAuthTokenSet

Token set returned by an OAuth provider after a code exchange or refresh.

import { OAuthTokenSet } from '@loopstack/oauth';
export interface OAuthTokenSet {
accessToken: string;
refreshToken?: string;
expiresIn?: number;
scope: string;
}

StoredTokens

Persisted OAuth token record held by OAuthTokenStore.

import { StoredTokens } from '@loopstack/oauth';
export interface StoredTokens {
accessToken: string;
refreshToken?: string;
expiresAt?: number;
scope: string;
}

Type Aliases

BuildOAuthUrlArgs

Args for BuildOAuthUrlTool.

import { BuildOAuthUrlArgs } from '@loopstack/oauth';
export type BuildOAuthUrlArgs = z.infer<typeof BuildOAuthUrlSchema>;

ExchangeOAuthTokenArgs

Args for ExchangeOAuthTokenTool.

import { ExchangeOAuthTokenArgs } from '@loopstack/oauth';
export type ExchangeOAuthTokenArgs = z.infer<typeof ExchangeOAuthTokenSchema>;

ExchangeOAuthTokenResult

Result for ExchangeOAuthTokenTool.

import { ExchangeOAuthTokenResult } from '@loopstack/oauth';
export type ExchangeOAuthTokenResult = {
accessToken: string;
refreshToken: string | undefined;
expiresIn: number | undefined;
scope: string | undefined;
};

Variables

BuildOAuthUrlResultSchema

Zod schema for BuildOAuthUrlResult — the resultSchema of build_oauth_url.

import { BuildOAuthUrlResultSchema } from '@loopstack/oauth';
BuildOAuthUrlResultSchema: z.ZodObject<
{
authUrl: z.ZodString;
state: z.ZodString;
},
z.core.$strict
>;

BuildOAuthUrlSchema

Zod schema for BuildOAuthUrlTool args.

import { BuildOAuthUrlSchema } from '@loopstack/oauth';
BuildOAuthUrlSchema: z.ZodObject<
{
provider: z.ZodString;
scopes: z.ZodArray<z.ZodString>;
},
z.core.$strict
>;

ExchangeOAuthTokenResultSchema

Zod schema for ExchangeOAuthTokenResult — the resultSchema of exchange_oauth_token.

import { ExchangeOAuthTokenResultSchema } from '@loopstack/oauth';
ExchangeOAuthTokenResultSchema: z.ZodObject<
{
accessToken: z.ZodString;
refreshToken: z.ZodOptional<z.ZodString>;
expiresIn: z.ZodOptional<z.ZodNumber>;
scope: z.ZodOptional<z.ZodString>;
},
z.core.$strict
>;

ExchangeOAuthTokenSchema

Zod schema for ExchangeOAuthTokenTool args.

import { ExchangeOAuthTokenSchema } from '@loopstack/oauth';
ExchangeOAuthTokenSchema: z.ZodObject<
{
provider: z.ZodString;
code: z.ZodString;
state: z.ZodString;
expectedState: z.ZodString;
},
z.core.$strict
>;

OAuthPromptDocumentSchema

Zod schema for OAuthPromptDocument.

import { OAuthPromptDocumentSchema } from '@loopstack/oauth';
OAuthPromptDocumentSchema: z.ZodObject<
{
provider: z.ZodString;
authUrl: z.ZodString;
state: z.ZodString;
status: z.ZodDefault<
z.ZodEnum<{
error: 'error';
success: 'success';
pending: 'pending';
}>
>;
message: z.ZodOptional<z.ZodString>;
},
z.core.$strict
>;