@leancodepl/api-proxy
v0.7.0
Published
LeanCode contacts generator nest api proxy with auth token forwarder
Readme
api-proxy
Handles authentication and communication with a contractsgenerator-based API. Supports JWT (e.g. JWKS) and Ory Kratos session validation (cookie or Bearer token).
Installation
npm install @leancodepl/api-proxyAPI
ApiProxyModule.register(config)
Registers the API proxy module with synchronous configuration.
- Parameters
config: ApiProxySyncConfiguration– Synchronous module configurationisGlobal?: boolean– Register the module globallyjwtStrategyConfig?: JwtStrategyConfig– Enable JWT (JWKS) authenticationkratosStrategyConfig?: KratosStrategyConfig– Enable Ory Kratos authentication
- Returns
DynamicModule– NestJS dynamic module
ApiProxyModule.registerAsync(options)
Registers the API proxy module with asynchronous configuration. Behavior matches Nest custom providers; one of useClass, useExisting, or useFactory is required.
- Parameters
options: ApiProxyAsyncConfiguration– Async module configuration (extendsPick<ModuleMetadata, "imports">)imports?: ModuleMetadata["imports"]– Modules to importuseExisting?: Type<ApiProxyConfigurationFactory>– Use existing configuration factoryuseClass?: Type<ApiProxyConfigurationFactory>– Use class as configuration factoryuseFactory?: (...args: any[]) => ApiProxyConfiguration | Promise<ApiProxyConfiguration>– Factory functioninject?: any[]– Tokens to inject into the factoryextraProviders?: Provider[]– Additional providersisGlobal?: boolean– Register the module globally
- Returns
DynamicModule– NestJS dynamic module
- Throws
NotFoundException– When none ofuseClass,useExisting, oruseFactoryis specified
UseJwtGuard()
Returns a guard that applies JWT (Passport) authentication. Use on controllers when defaultStrategy is "jwt" or pass the strategy explicitly.
- Returns
- Decorator that applies
AuthGuard("jwt")
- Decorator that applies
UseKratosGuard()
Returns a guard that applies Ory Kratos (Passport) authentication. Validates via Kratos toSession (cookie or Authorization: Bearer <session_token>). Use on controllers when defaultStrategy is "kratos" or pass the strategy explicitly.
- Returns
- Decorator that applies
AuthGuard("kratos")
- Decorator that applies
CqrsClientFactory
Injectable factory that creates a CQRS API client bound to the current request (for token forwarding).
- Constructor
httpService: HttpService– From"@nestjs/axios"request: Request– Current request (injected viaREQUEST)
- Methods
create(getApiEndpoint)– Returns anApiinstance using the given endpoint getter- Parameters
getApiEndpoint: EndpointGetter– Function that returns the API base URL for a given type
- Returns
CqrsClient– API client instance
- Parameters
Api
Implements CqrsClient. Sends requests to the API using the request’s auth data: Bearer token (from JWT or Kratos) and, when using Kratos, the session cookie (forwarded as Cookie header).
- Constructor
httpService: HttpService– HTTP service instancerequest: Request– Current requestgetApiEndpoint: EndpointGetter– Function that returns the API base URL for a given type
- Methods
createQuery<TQuery, TResult>(type)– Returns a function that runs a query- Parameters
type: string– Query type (used to resolve endpoint)
- Returns
(dto: TQuery) => Promise<TResult>
- Parameters
createCommand<TCommand, TErrorCodes>(type)– Returns a function that runs a command- Parameters
type: string– Command type (used to resolve endpoint)
- Returns
(dto: TCommand) => Promise<CommandResult<TErrorCodes>>
- Parameters
CqrsClient
Interface for CQRS API clients: createQuery(type) and createCommand(type).
EndpointGetter
Type: (type: string) => string. Function that returns the API base URL for a given type.
JwtStrategy
Passport strategy for JWT (JWKS) authentication.
- Constructor
jwtStrategyConfig: JwtStrategyConfig– JWT strategy configurationjwksUri: string– JWKS endpoint URLjsonWebTokenOptions?: VerifyOptions– Options from"jsonwebtoken"(e.g.audience,issuer)
KratosStrategy
Passport strategy for Ory Kratos session validation. Accepts either a cookie (from Cookie header) or a Bearer token (Authorization: Bearer <session_token>); at least one must be present. Validates via Kratos toSession and attaches { token, cookie } to the request user for downstream forwarding.
- Constructor
kratosStrategyConfig: KratosStrategyConfig– Kratos strategy configurationkratosPublicUrl: string– Ory Kratos public API base URL (e.g.http://localhost:4433)
validate(req)- Returns –
{ token?: string; cookie?: string }– The session token and/or cookie string passed to the request (for use byApiwhen calling the backend)
- Returns –
Types
ApiProxySyncConfiguration–ApiProxyConfiguration & { isGlobal?: boolean }ApiProxyConfiguration–{ jwtStrategyConfig?: JwtStrategyConfig; kratosStrategyConfig?: KratosStrategyConfig }ApiProxyAsyncConfiguration– Async module options (seeregisterAsync)ApiProxyConfigurationFactory–{ createApiProxyConfiguration(): ApiProxyConfiguration | Promise<ApiProxyConfiguration> }JwtStrategyConfig–{ jwksUri: string; jsonWebTokenOptions?: VerifyOptions }(VerifyOptionsfrom"jsonwebtoken")KratosStrategyConfig–{ kratosPublicUrl: string }(Ory Kratos public API base URL)
Symbols
InstanceToken– Injection token for the proxy instanceApiAndAuthConfigurationToken– Injection token for API/auth configuration
Usage Examples
Register module (sync, JWT)
import { Module } from "@nestjs/common";
import { PassportModule } from "@nestjs/passport";
import { ApiProxyModule } from "@leancodepl/api-proxy";
const config = {
isGlobal: false,
jwtStrategyConfig: {
jwksUri: "https://localhost:3333/auth/.well-known/openid-configuration/jwks",
jsonWebTokenOptions: { audience: "internal_api" },
},
};
@Module({
imports: [
ApiProxyModule.register(config),
PassportModule.register({ defaultStrategy: "jwt" }),
],
})
export class AppModule {}Register module (sync, Kratos)
import { Module } from "@nestjs/common";
import { PassportModule } from "@nestjs/passport";
import { ApiProxyModule } from "@leancodepl/api-proxy";
@Module({
imports: [
ApiProxyModule.register({
isGlobal: false,
kratosStrategyConfig: { kratosPublicUrl: "http://localhost:4433" },
}),
PassportModule.register({ defaultStrategy: "kratos" }),
],
})
export class AppModule {}Register module (async, with ConfigService)
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { PassportModule } from "@nestjs/passport";
import { ApiProxyModule } from "@leancodepl/api-proxy";
@Module({
imports: [
ConfigModule.forRoot(),
ApiProxyModule.registerAsync({
isGlobal: false,
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
jwtStrategyConfig: {
jwksUri: config.get("JWKS_URI") ?? "",
jsonWebTokenOptions: { audience: "internal_api" },
},
}),
inject: [ConfigService],
}),
PassportModule.register({ defaultStrategy: "jwt" }),
],
})
export class AppModule {}Use JWT guard on a controller
import { Controller } from "@nestjs/common";
import { UseJwtGuard } from "@leancodepl/api-proxy";
@UseJwtGuard()
@Controller()
export class AppController {}Use Kratos guard on a controller
import { Controller } from "@nestjs/common";
import { UseKratosGuard } from "@leancodepl/api-proxy";
@UseKratosGuard()
@Controller("kratos")
export class KratosController {}Provide a CQRS client and use it
import { Injectable, Module } from "@nestjs/common";
import { ApiProxyModule, CqrsClientFactory } from "@leancodepl/api-proxy";
import { PassportModule } from "@nestjs/passport";
import Client from "./Client"; // from contractsgenerator-typescript
@Injectable()
export class CqrsClient1 {
client;
constructor(cqrsClientFactory: CqrsClientFactory) {
this.client = Client(cqrsClientFactory.create((type) => `http://localhost:3333/api/${type}`));
}
}
@Module({
imports: [
ApiProxyModule.register({ jwtStrategyConfig: { jwksUri: "https://..." } }),
PassportModule.register({ defaultStrategy: "jwt" }),
],
providers: [CqrsClient1],
})
export class AppModule {}Configuration
- JWT: Set
jwksUriand optionallyjsonWebTokenOptions(e.g.audience,issuer) from"jsonwebtoken"VerifyOptions. - Kratos: Set
kratosPublicUrlto your Kratos public API base (e.g.http://localhost:4433). The strategy uses the KratostoSessionAPI with cookie orAuthorization: Bearer <session_token>. TheApiservice forwards both the session token (as Bearer) and the cookie to the backend when making CQRS requests.
