Node.js SDK API Reference
Complete API reference for Hawcx OAuth Client SDK for Node.js
Node.js SDK API Reference
OAuth Exchange
exchangeCodeForClaims(options)
Exchanges a Hawcx authorization code for verified JWT claims.
Parameters:
interface ExchangeCodeForClaimsOptions {
code: string; // Authorization code from Hawcx
oauthTokenUrl: string; // Token endpoint URL
clientId: string; // OAuth client ID
apiKey: string; // API key for Hawcx OAuth (required)
publicKey?: string | Buffer; // Public key (PEM string or file path) - optional if jwksUrl provided
jwksUrl?: string; // JWKS URL for dynamic key fetching (alternative to publicKey)
codeVerifier?: string; // PKCE code verifier (optional)
audience?: string; // Expected 'aud' claim (optional)
issuer?: string; // Expected 'iss' claim (optional)
leeway?: number; // Clock skew tolerance in seconds (default: 0)
}Returns:
interface Claims {
sub: string; // Subject (user ID)
email: string; // User email
email_verified: boolean; // Whether email is verified
aud: string; // Audience
iss: string; // Issuer
iat: number; // Issued at (Unix timestamp)
exp: number; // Expiration (Unix timestamp)
[key: string]: any; // Additional claims
}Throws:
OAuthExchangeError- Failed to exchange code for tokenJWTVerificationError- JWT signature or claims validation failedInvalidPublicKeyError- Public key is malformed
Example:
try {
const claims = await exchangeCodeForClaims({
code: 'auth_code_from_client',
oauthTokenUrl: 'https://example.hawcx.com/oauth2/token',
clientId: 'your_client_id',
apiKey: process.env.HAWCX_API_KEY!,
jwksUrl: 'https://example.hawcx.com/.well-known/jwks.json',
audience: 'your_client_id'
});
console.log('User ID:', claims.sub);
console.log('Email:', claims.email);
} catch (error) {
console.error('Exchange failed:', error.message);
}JWT Verification
verifyJwt(token, publicKey, options?)
Manually verify a JWT token using the provided public key.
Parameters:
interface VerifyJwtOptions {
algorithms?: string[]; // Allowed algorithms (default: ['RS256'])
audience?: string; // Expected 'aud' claim
issuer?: string; // Expected 'iss' claim
leeway?: number; // Clock skew tolerance in seconds
}Returns:
interface JwtPayload {
[key: string]: any;
}Example:
import { verifyJwt } from '@hawcx/oauth-client';
const payload = verifyJwt(token, publicKey, {
audience: 'my-app',
issuer: 'https://example.hawcx.com'
});Delegation Client
The HawcxDelegationClient provides high-level APIs for managing user MFA settings and credentials.
HawcxDelegationClient.fromKeys(options)
Initialize the delegation client with explicit cryptographic keys.
Parameters:
interface DelegationClientOptions {
spSigningKey: string; // Service provider ED25519 private key (PEM)
spEncryptionKey: string; // Service provider X25519 private key (PEM)
idpVerifyKey: string; // Identity provider ED25519 public key (PEM)
idpEncryptionKey: string; // Identity provider X25519 public key (PEM)
baseUrl: string; // Hawcx base URL
spId: string; // Service provider ID (usually your client ID)
}Example:
import { HawcxDelegationClient } from '@hawcx/oauth-client';
const client = HawcxDelegationClient.fromKeys({
spSigningKey: process.env.SP_ED25519_PRIVATE_KEY_PEM,
spEncryptionKey: process.env.SP_X25519_PRIVATE_KEY_PEM,
idpVerifyKey: process.env.IDP_ED25519_PUBLIC_KEY_PEM,
idpEncryptionKey: process.env.IDP_X25519_PUBLIC_KEY_PEM,
baseUrl: process.env.HAWCX_BASE_URL!,
spId: process.env.OAUTH_CLIENT_ID,
apiKey: process.env.HAWCX_API_KEY
});initiateMfaChange(options)
Initiate MFA setup or change for a user.
Parameters:
interface InitiateMfaChangeOptions {
userid: string; // User email or ID
mfaMethod: MfaMethod; // MFA method (EMAIL, SMS, TOTP)
phoneNumber?: string; // Phone number (required for SMS)
}
enum MfaMethod {
EMAIL = 'email',
SMS = 'sms',
TOTP = 'totp'
}Returns:
interface MfaChangeResult {
session_id: string; // Session ID for verification
status: string;
message?: string;
}Example:
import { MfaMethod } from '@hawcx/oauth-client';
const result = await client.initiateMfaChange({
userid: '[email protected]',
mfaMethod: MfaMethod.SMS,
phoneNumber: '+15551234567'
});
console.log('Session ID:', result.session_id);verifyMfaChange(options)
Verify OTP and complete MFA setup or change.
Parameters:
interface VerifyMfaChangeOptions {
userid: string; // User email or ID
sessionId: string; // Session ID from initiateMfaChange
otp: string; // One-time password (6 digits)
}Returns:
interface VerifyMfaChangeResult {
status: 'success' | 'failed';
message?: string;
}Example:
const result = await client.verifyMfaChange({
userid: '[email protected]',
sessionId: sessionFromInitiate,
otp: '123456'
});
if (result.status === 'success') {
console.log('MFA setup complete!');
}getUserCredentials(userid)
Retrieve the current MFA method and credentials for a user.
Parameters:
userid(string) - User email or ID
Returns:
interface UserCredentials {
mfa_method: string; // Current MFA method
status: string;
message?: string;
}Example:
const creds = await client.getUserCredentials('[email protected]');
console.log('Current MFA:', creds.mfa_method);Exception Types
OAuthExchangeError
Thrown when OAuth code exchange fails.
try {
await exchangeCodeForClaims(options);
} catch (error) {
if (error instanceof OAuthExchangeError) {
console.error('OAuth error:', error.message);
}
}JWTVerificationError
Thrown when JWT signature or claims validation fails.
try {
verifyJwt(token, publicKey);
} catch (error) {
if (error instanceof JWTVerificationError) {
console.error('JWT verification failed:', error.message);
}
}InvalidPublicKeyError
Thrown when the provided public key is malformed.
try {
await exchangeCodeForClaims({
publicKey: 'invalid-key'
});
} catch (error) {
if (error instanceof InvalidPublicKeyError) {
console.error('Key format error:', error.message);
}
}Type Definitions
All types are fully exported and available for import:
import {
Claims,
JwtPayload,
MfaMethod,
ExchangeCodeForClaimsOptions,
UserCredentials,
OAuthExchangeError,
JWTVerificationError,
InvalidPublicKeyError,
HawcxDelegationClient
} from '@hawcx/oauth-client';Best Practices
1. Environment Variable Management
// Use environment variables for all sensitive keys
const client = HawcxDelegationClient.fromEnv();2. Error Handling
import {
exchangeCodeForClaims,
OAuthExchangeError,
JWTVerificationError
} from '@hawcx/oauth-client';
try {
const claims = await exchangeCodeForClaims({
code: authCode,
oauthTokenUrl: process.env.OAUTH_TOKEN_ENDPOINT!,
clientId: process.env.OAUTH_CLIENT_ID!,
apiKey: process.env.HAWCX_API_KEY!,
jwksUrl: process.env.JWKS_URL!
});
} catch (error) {
if (error instanceof OAuthExchangeError) {
// Handle OAuth errors (invalid code, expired, etc.)
} else if (error instanceof JWTVerificationError) {
// Handle JWT validation errors
} else {
throw error;
}
}3. Clock Skew Tolerance
For distributed systems, add clock skew tolerance:
const claims = await exchangeCodeForClaims({
code: authCode,
oauthTokenUrl: tokenEndpoint,
clientId: clientId,
apiKey: process.env.HAWCX_API_KEY!,
jwksUrl: process.env.JWKS_URL!,
leeway: 10 // Allow 10 seconds of clock skew
});4. MFA Flow
// Step 1: Initiate
const mfaSession = await client.initiateMfaChange({
userid: '[email protected]',
mfaMethod: MfaMethod.SMS,
phoneNumber: '+15551234567'
});
// Step 2: User receives OTP via SMS
// Step 3: Verify
const result = await client.verifyMfaChange({
userid: '[email protected]',
sessionId: mfaSession.session_id,
otp: userProvidedOtp
});
if (result.status === 'success') {
// MFA setup complete
}Environment Variables
Configure these required variables:
For OAuth Code Exchange:
# Required
HAWCX_API_KEY=your_api_key
OAUTH_TOKEN_ENDPOINT=https://example.hawcx.com/oauth2/token
OAUTH_CLIENT_ID=your_client_id
# Choose one: static public key OR JWKS URL (JWKS recommended)
JWKS_URL=https://example.hawcx.com/.well-known/jwks.json
# OR
OAUTH_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----\n...
# Optional but recommended
OAUTH_ISSUER=https://example.hawcx.com
OAUTH_AUDIENCE=your_client_idFor Hawcx Delegation:
HAWCX_BASE_URL=https://example.hawcx.com
HAWCX_API_KEY=your_api_key
SP_ED25519_PRIVATE_KEY_PEM=-----BEGIN PRIVATE KEY-----\n...
SP_X25519_PRIVATE_KEY_PEM=-----BEGIN PRIVATE KEY-----\n...
IDP_ED25519_PUBLIC_KEY_PEM=-----BEGIN PUBLIC KEY-----\n...
IDP_X25519_PUBLIC_KEY_PEM=-----BEGIN PUBLIC KEY-----\n...
OAUTH_CLIENT_ID=your_client_id