Quik Framework :: OAuth Server
- Codename: Berlin
- Version: 0.2.0-beta.76
- License: Check license here
@quik/oauth-server provides OAuth server primitives for running your app as an authorization provider.
Installation
pnpm add @quik/oauth-server
What The Module Does
- Loads OAuth server locales.
- Registers
QOAuthServerServiceinServicesStore. - Registers API OAuth endpoints when HTTP engine is available.
- Supports authorization code flow with PKCE verification.
- Supports refresh token flow with optional rotation.
- Supports client credentials flow.
- Exposes JWKS public key metadata for token validation.
- Exposes token introspection and revocation endpoints.
- Provides consent store contracts for client/user scope approvals.
Configuration (oauth.server)
oauth.server.enabledfromOAUTH_SERVER_ENABLEDdefaultfalse.oauth.server.issuerfromOAUTH_SERVER_ISSUERdefaulthttp://localhost:3000.oauth.server.http.authenticationPrefixfromOAUTH_SERVER_HTTP_AUTHENTICATION_PREFIXdefault/auth.oauth.server.http.managementPrefixfromOAUTH_SERVER_HTTP_MANAGEMENT_PREFIXdefault/.oauth.server.authorizationCode.timeToLiveSecondsfromOAUTH_SERVER_AUTHORIZATION_CODE_TIME_TO_LIVE_SECONDSdefault300.oauth.server.accessToken.timeToLiveSecondsfromOAUTH_SERVER_ACCESS_TOKEN_TIME_TO_LIVE_SECONDSdefault3600.oauth.server.refreshToken.timeToLiveSecondsfromOAUTH_SERVER_REFRESH_TOKEN_TIME_TO_LIVE_SECONDSdefault2592000.oauth.server.pkce.requiredByDefaultfromOAUTH_SERVER_PKCE_REQUIRED_BY_DEFAULTdefaulttrue.oauth.server.refreshToken.rotateOnUsefromOAUTH_SERVER_REFRESH_TOKEN_ROTATE_ON_USEdefaulttrue.oauth.server.jwks.keyIdentifierfromOAUTH_SERVER_JWKS_KEY_IDENTIFIERdefaultoauth-server-default.oauth.server.jwks.rsaModulusLengthfromOAUTH_SERVER_JWKS_RSA_MODULUS_LENGTHdefault2048.oauth.server.jwks.signing.privateKeyPemfromOAUTH_SERVER_JWKS_SIGNING_PRIVATE_KEY_PEMdefault empty.oauth.server.jwks.signing.publicKeyPemfromOAUTH_SERVER_JWKS_SIGNING_PUBLIC_KEY_PEMdefault empty.oauth.server.jwks.signing.allowGeneratedFallbackfromOAUTH_SERVER_JWKS_SIGNING_ALLOW_GENERATED_FALLBACKdefaulttrueonly whenNODE_ENV=development, otherwisefalse.
Built-In API Endpoints
Authentication routes are registered under:
http.paths.api+oauth.server.http.authenticationPrefix+/oauth.
Client management routes are registered under:
http.paths.api+oauth.server.http.managementPrefix+/oauth/clients.
Default paths become:
POST /api/auth/oauth/authorize.POST /api/auth/oauth/token.POST /api/auth/oauth/introspect.POST /api/auth/oauth/revoke.GET /api/auth/oauth/.well-known/jwks.json.POST /api/oauth/clients/.GET /api/oauth/clients/.GET /api/oauth/clients/:clientId.PATCH /api/oauth/clients/:clientId.DELETE /api/oauth/clients/:clientId.
Request parameters for these endpoints are defined as typed entities in src/entities/:
- OAuthAuthorizeRequestBody.ts
- OAuthTokenRequestBody.ts
- OAuthIntrospectRequestBody.ts
- OAuthRevokeRequestBody.ts
Quick Usage
import { ServicesStore } from '@quik/services';
import { QOAuthServerService } from '@quik/oauth-server';
const oauth = ServicesStore.get(QOAuthServerService);
oauth.assertEnabled();
oauth.registerClient({
id: 'web-app',
type: 'public',
redirectUris: [ 'https://app.example.com/callback' ],
allowedGrantTypes: [ 'authorization_code', 'refresh_token' ]
});
const authCode = oauth.createAuthorizationCode({
clientId: 'web-app',
userId: 'user-1',
redirectUri: 'https://app.example.com/callback',
scope: [ 'profile' ],
codeChallenge: 'S256_HASH',
codeChallengeMethod: 'S256'
});
const token = await oauth.exchangeAuthorizationCode({
clientId: 'web-app',
code: authCode.code,
redirectUri: 'https://app.example.com/callback',
codeVerifier: 'verifier-value'
});
const jwks = oauth.getJWKS();
const introspection = oauth.introspectToken({
clientId: 'web-app',
token: token.accessToken
});
oauth.revokeToken({
clientId: 'web-app',
token: String(token.refreshToken),
tokenTypeHint: 'refresh_token'
});
Store Extensibility
- Replace active stores with
setOAuthClientStore,setOAuthAuthorizationCodeStore,setOAuthRefreshTokenStore, andsetOAuthConsentStore. - Build repository-backed consent stores by extending
QAbstractOAuthConsentStore.
import { QAbstractOAuthConsentStore, type QOAuthConsent } from '@quik/oauth-server';
class DBConsentStore extends QAbstractOAuthConsentStore<MyConsentRepository> {
protected persistConsent(consent: QOAuthConsent): QOAuthConsent {
return this.repository.upsert(consent);
}
protected fetchConsent(id: string): QOAuthConsent | undefined {
return this.repository.findById(id);
}
protected findConsent(clientId: string, userId: string): QOAuthConsent | undefined {
return this.repository.findByClientAndUser(clientId, userId);
}
protected removeConsent(id: string): void {
this.repository.deleteById(id);
}
protected clearConsents(): void {
this.repository.deleteAll();
}
protected removeRevoked(now: number): number {
return this.repository.deleteRevokedSince(now);
}
}
API Reference
Generated API documentation is available in the oauth-server API section.