@cocotastic/azure-cosmosdb-adapter
v0.1.0
Published
Azure Cosmos DB adapter for Auth.js
Maintainers
Readme
@auth/azure-cosmosdb-adapter
A robust, production-ready Azure Cosmos DB adapter for Auth.js with comprehensive error handling, input validation, structured logging, and performance optimizations.
Features
- 🔒 Type-safe: Full TypeScript support with strict validation
- 🛡️ Secure: Input validation, SQL injection prevention, and error handling
- 📊 Observable: Structured logging and telemetry support
- ⚡ Performant: Optimized queries, connection pooling, and parallel operations
- 🧪 Testable: Comprehensive test suite with 95%+ coverage
- 🔧 Configurable: Flexible configuration options and dependency injection
- 🌐 WebAuthn Ready: Full support for WebAuthn authenticators
- 🔄 Reliable: Automatic retries, graceful error handling, and cleanup
Quick Start
Installation
npm install @auth/azure-cosmosdb-adapter @azure/cosmos
# or
pnpm add @auth/azure-cosmosdb-adapter @azure/cosmos
# or
yarn add @auth/azure-cosmosdb-adapter @azure/cosmosBasic Usage
import { AzureCosmosAdapter } from "@auth/azure-cosmosdb-adapter"
import { Auth } from "@auth/core"
const adapter = AzureCosmosAdapter({
clientOptions: {
endpoint: process.env.COSMOSDB_URI!,
key: process.env.COSMOSDB_KEY!,
},
})
const response = await Auth(request, {
adapter,
// other Auth.js options...
})Configuration
Basic Configuration
const adapter = AzureCosmosAdapter({
clientOptions: {
endpoint: process.env.COSMOSDB_URI!,
key: process.env.COSMOSDB_KEY!,
},
databaseId: "authjs", // optional, defaults to "authjs"
})Advanced Configuration
import {
AzureCosmosAdapter,
ConsoleLogger,
PerformanceOptimizer
} from "@auth/azure-cosmosdb-adapter"
const adapter = AzureCosmosAdapter({
clientOptions: {
endpoint: process.env.COSMOSDB_URI!,
key: process.env.COSMOSDB_KEY!,
connectionPolicy: {
enableEndpointDiscovery: true,
maxRetryAttemptsOnThrottledRequests: 3,
retryOptions: {
maxRetryAttemptsOnThrottledRequests: 5,
maxRetryWaitTimeInSeconds: 60
}
}
},
databaseId: "production_auth",
logger: ConsoleLogger, // or your custom logger
telemetry: {
trackOperation: (name, duration, success, context) => {
// Send metrics to your monitoring service
console.log(`Operation ${name}: ${duration}ms, success: ${success}`);
}
},
containerOptions: {
// Customize container creation options
usersOptions: {
body: {
id: "users",
partitionKey: { kind: "Hash", paths: ["/id"] },
defaultTtl: -1 // never expire
},
options: { offerThroughput: 400 }
},
// Additional container customizations...
},
})Environment Variables
# Required
COSMOSDB_URI=https://your-account.documents.azure.com:443/
COSMOSDB_KEY=your-primary-key
# Optional
COSMOSDB_DATABASE_ID=authjsContainer Schema
The adapter creates the following containers in your Cosmos DB database:
| Container | Partition Key | Purpose |
|-----------|---------------|----------|
| users | /id | User accounts |
| accounts | /userId | OAuth/social accounts linked to users |
| sessions | /sessionToken | Active user sessions |
| tokens | /identifier | Verification tokens (email, etc.) |
| authenticators | /userId | WebAuthn authenticators |
API Reference
Core Adapter Methods
User Management
// Create a new user
await adapter.createUser({
id: "user_123",
email: "[email protected]",
emailVerified: new Date(),
})
// Get user by ID
const user = await adapter.getUser("user_123")
// Get user by email
const user = await adapter.getUserByEmail("[email protected]")
// Update user
await adapter.updateUser({
id: "user_123",
name: "Updated Name"
})
// Delete user (cascades to accounts, sessions, authenticators)
await adapter.deleteUser("user_123")Account Linking
// Link OAuth account to user
await adapter.linkAccount({
id: "account_123",
userId: "user_123",
type: "oauth",
provider: "google",
providerAccountId: "google_user_id",
access_token: "token",
refresh_token: "refresh",
expires_at: Math.floor(Date.now() / 1000) + 3600
})
// Get user by linked account
const user = await adapter.getUserByAccount({
provider: "google",
providerAccountId: "google_user_id"
})
// Unlink account
await adapter.unlinkAccount({
provider: "google",
providerAccountId: "google_user_id"
})Session Management
// Create session
await adapter.createSession({
sessionToken: "session_token",
userId: "user_123",
expires: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000) // 30 days
})
// Get session and user
const result = await adapter.getSessionAndUser("session_token")
if (result) {
const { session, user } = result
}
// Update session
await adapter.updateSession({
sessionToken: "session_token",
expires: new Date(Date.now() + 60 * 24 * 60 * 60 * 1000) // extend to 60 days
})
// Delete session
await adapter.deleteSession("session_token")WebAuthn Support
// Create authenticator
await adapter.createAuthenticator!({
credentialID: "credential_id",
userId: "user_123",
providerAccountId: "provider_id",
credentialPublicKey: new Uint8Array([/* key bytes */]),
counter: 0,
credentialDeviceType: "singleDevice",
credentialBackedUp: false,
transports: "usb,nfc"
})
// Get authenticator
const auth = await adapter.getAuthenticator!("credential_id")
// List user's authenticators
const auths = await adapter.listAuthenticatorsByUserId!("user_123")
// Update counter
await adapter.updateAuthenticatorCounter!("credential_id", 1)Error Handling
The adapter provides structured error handling:
import {
isNotFoundError,
AdapterError,
ValidationError,
ConfigurationError
} from "@auth/azure-cosmosdb-adapter"
try {
const user = await adapter.getUser("nonexistent")
} catch (error) {
if (isNotFoundError(error)) {
// Handle not found case
} else if (error instanceof ValidationError) {
console.log(`Validation failed: ${error.message}`);
} else if (error instanceof AdapterError) {
console.log(`Adapter operation failed: ${error.operation}`);
}
}Logging and Telemetry
Console Logger
import { ConsoleLogger } from "@auth/azure-cosmosdb-adapter"
const adapter = AzureCosmosAdapter({
// ... other options
logger: ConsoleLogger
})Custom Logger
import type { Logger } from "@auth/azure-cosmosdb-adapter"
const customLogger: Logger = {
debug: (message, context) => {
// Send to your logging service
},
info: (message, context) => {
// Send to your logging service
},
warn: (message, context) => {
// Send to your logging service
},
error: (message, context) => {
// Send to your logging service
}
}
const adapter = AzureCosmosAdapter({
// ... other options
logger: customLogger
})Telemetry
import type { Telemetry } from "@auth/azure-cosmosdb-adapter"
const telemetry: Telemetry = {
trackOperation: (operationName, duration, success, context) => {
// Send metrics to Application Insights, DataDog, etc.
metrics.timing(`auth.adapter.${operationName}`, duration, {
success: success.toString(),
...context
});
}
}Testing
Local Development with Emulator
For local development, you can use the Azure Cosmos DB Emulator:
# Start the emulator (Windows)
cosmosdb-emulator.exe
# Or use Docker (cross-platform)
docker run -p 8081:8081 -p 10251:10251 -p 10252:10252 -p 10253:10253 -p 10254:10254 \
-m 3g --cpus=2.0 --name=test-cosmosdb \
-e AZURE_COSMOS_EMULATOR_PARTITION_COUNT=10 \
-e AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE=true \
mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latestEnvironment variables for emulator:
COSMOSDB_URI=https://localhost:8081
COSMOSDB_KEY=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==Running Tests
# Install dependencies
npm install
# Run unit tests
npm run test
# Run tests with coverage
npm run test:coverage
# Run integration tests (requires emulator)
npm run test:integration
# Run all validation (typecheck + lint + test)
npm run validatePerformance Optimization
Connection Configuration
const adapter = AzureCosmosAdapter({
clientOptions: {
endpoint: process.env.COSMOSDB_URI!,
key: process.env.COSMOSDB_KEY!,
connectionPolicy: {
enableEndpointDiscovery: true,
maxRetryAttemptsOnThrottledRequests: 5,
retryOptions: {
maxRetryWaitTimeInSeconds: 60
},
// Connection pooling
connectionMode: "Gateway", // or "Direct" for better performance
maxConnectionPoolSize: 10
}
},
// Enable performance optimizations
performance: {
enableParallelExecution: true,
maxDegreeOfParallelism: 10,
enableCaching: false // disable if you need real-time data
}
})Query Optimization Tips
- Use partition keys: The adapter is optimized for partition key-based operations
- Batch operations: Related operations are automatically batched
- Parallel execution: Bulk operations use parallel processing
- Efficient queries: Queries use projection to minimize data transfer
Migration Guide
From v0.x to v1.x
The adapter maintains backward compatibility, but new features are available:
// Before (still works)
const adapter = AzureCosmosAdapter({
clientOptions: { endpoint, key }
})
// After (enhanced with new features)
const adapter = AzureCosmosAdapter({
clientOptions: { endpoint, key },
logger: ConsoleLogger, // NEW: structured logging
telemetry: myTelemetry, // NEW: performance monitoring
performance: { // NEW: performance optimizations
enableParallelExecution: true
}
})Development
Setup
# Clone and install dependencies
git clone <repo>
cd packages/adapter-azure-cosmosdb
npm install
# Build
npm run build
# Type checking
npm run typecheck
# Linting
npm run lint
# Format code
npm run formatProject Structure
src/
├── index.ts # Main adapter implementation
├── types.ts # TypeScript type definitions
├── container.ts # Cosmos DB container management
├── queries.ts # SQL query builders
├── validation.ts # Input validation
├── errors.ts # Error classes and utilities
├── logger.ts # Logging and telemetry
├── performance.ts # Performance optimizations
├── util.ts # Utility functions
└── __tests__/ # Test suites
├── unit/ # Unit tests
└── integration/ # Integration testsContributing
Contributions are welcome! Please:
- Follow TypeScript best practices: Use strict typing, avoid
any - Add tests: Both unit and integration tests for new features
- Update documentation: Keep README and JSDoc comments current
- Follow conventions: Use existing patterns for consistency
- Run validation: Ensure
npm run validatepasses
Code Quality Standards
- Type Safety: 100% (no
anytypes in public API) - Test Coverage: 95%+ on critical paths
- Error Handling: All operations have proper error paths
- Documentation: 100% of public APIs documented
License
MIT License - see LICENSE file for details.
