Absolute Auth
A comprehensive TypeScript-based authentication system built for Elysia applications. Complete OAuth 2.0 solution with optional OpenID Connect capabilities and end-to-end type safety.
View on GitHubKey Features
Multi-Provider Support
66 OAuth 2.0 providers with OpenID Connect support
Type-Safe
Full TypeScript support with comprehensive type definitions
Session Management
Built-in session handling with automatic expiration
Token Management
Automatic token refresh and revocation support
Route Protection
Easy-to-use route protection with typed callbacks
Event Hooks
Customizable handlers for all authentication flows
PKCE Support
Automatic PKCE implementation for supported providers
Security
Secure cookie handling and CSRF protection built-in
Installation
bun install @absolutejs/authBasic Setup
1import { Elysia } from 'elysia';
2import { absoluteAuth } from '@absolutejs/auth';
3import { getEnv } from '@absolutejs/absolute';
4
5const app = new Elysia()
6 .use(absoluteAuth<User>({
7 providersConfiguration: {
8 google: {
9 credentials: {
10 clientId: getEnv('GOOGLE_CLIENT_ID'),
11 clientSecret: getEnv('GOOGLE_CLIENT_SECRET'),
12 redirectUri: 'http://localhost:3000/oauth2/callback'
13 },
14 scope: ['openid', 'profile', 'email']
15 }
16 }
17 }))
18 .listen(3000);Protect Routes
The protectRoute helper function protects routes that require authentication. It accepts two callbacks with fully typed parameters - the user object matches your exact user shape, and the error object is one of the specific authentication errors, giving you complete type safety for both success and failure paths.
1app.get('/protected', ({ status, protectRoute }) =>
2 protectRoute(
3 (user) => {
4 return `Hello, ${user.name}!`;
5 },
6 (error) => status(error.code, error.message)
7 )
8);Handle Authentication Flow
When you use the Absolute Auth plugin, it automatically creates all the authentication routes you need. You do not implement your own login, status, or sign-out routes, you simply call the ones already provided.
Start the OAuth flow
1// Option 1: Use an anchor element
2<a href="/oauth2/google/authorization">Sign in with Google</a>
3
4// Option 2: Redirect the user to the provider's authorization URL
5redirect('/oauth2/google/authorization');This triggers the built-in authorization route, which handles:
- Generating state + PKCE (if required)
- Storing the provider name
- Storing the origin URL
- Building and redirecting to the provider's authorization URL
Check whether the user is logged in
1import { server } from '/src/frontend/utils/edenTreaty';
2
3const { data, error } = await server.oauth2.status.get();
4
5if (error) {
6 console.error('Not authenticated:', error);
7} else {
8 console.log('User:', data.user);
9}Sign the user out
1import { server } from '/src/frontend/utils/edenTreaty';
2
3const { data, error } = await server.oauth2.signout.delete();
4
5if (error) {
6 console.error('Signout failed:', error);
7} else {
8 console.log('Successfully signed out');
9}This calls the built-in sign-out route, which:
- Runs your onSignOut hook (if provided)
- Deletes the user session
- Clears authentication cookies
Authentication Routes
The library automatically creates the following routes:
| Route | Method | Description |
|---|---|---|
/oauth2/:provider/authorization | GET | Initiate OAuth flow with specified provider |
/oauth2/callback | GET | Handle OAuth callback and token exchange |
/oauth2/status | GET | Check current user authentication status |
/oauth2/profile | GET | Fetch user profile from OAuth provider |
/oauth2/tokens | POST | Refresh access token using refresh token |
/oauth2/revocation | POST | Revoke access or refresh token |
/oauth2/signout | DELETE | Sign out user and clear session |
Session Management
Absolute Auth provides automatic session management with configurable lifetimes and cleanup. Sessions are automatically cleaned up at regular intervals, and you can also trigger cleanup manually using the derived cleanupSessions function.
Configuration
Configure session behavior using millisecond-based options:
1.use(await absoluteAuth<User>({
2 providersConfiguration: { /* ... */ },
3
4 // Session lifetime configuration
5 sessionDurationMs: 86400000, // 24 hours (default)
6 unregisteredSessionDurationMs: 3600000, // 1 hour (default)
7 cleanupIntervalMs: 300000, // 5 minutes (default)
8 maxSessions: 5, // Max sessions per user (default)
9
10 // Called when sessions are cleaned up
11 onSessionCleanup: async ({ removedSessions, removedUnregisteredSessions }) => {
12 console.log(`Cleaned up ${removedSessions.size} expired sessions`);
13 }
14}))The cleanup process:
- Runs automatically at the interval specified by cleanupIntervalMs
- Removes sessions older than sessionDurationMs
- Removes unregistered sessions older than unregisteredSessionDurationMs
- Enforces the maxSessions limit per user, removing oldest sessions first
- Calls the onSessionCleanup hook with maps of removed sessions
The cleanupSessions Derived Function
When you use absoluteAuth, a cleanupSessions function is derived and made available in all your route handlers. This allows you to trigger cleanup programmatically:
1// The cleanupSessions function is derived from the auth middleware
2// and available in all route handlers
3
4app.post('/admin/cleanup', async ({ cleanupSessions }) => {
5 // Manually trigger session cleanup
6 await cleanupSessions();
7 return { message: 'Sessions cleaned up' };
8});
9
10// You can also use it in scheduled tasks
11app.get('/health', async ({ cleanupSessions }) => {
12 // Cleanup runs automatically via cleanupIntervalMs,
13 // but can be triggered manually if needed
14 await cleanupSessions();
15 return { status: 'healthy' };
16})The derived function follows Elysia's plugin pattern - it captures the session configuration from when absoluteAuth was initialized and provides a simple async function you can call from any route.
Custom User Handling
Absolute Auth does not provide database adapters. Instead, it exposes hooks throughout the OAuth lifecycle, allowing you to integrate any persistence layer or user model. These hooks provide full control over user creation, updates, and session handling while keeping the OAuth flow standardized and database-agnostic.
Core Hook: onCallbackSuccess
Called after the provider returns and tokens are exchanged. Use it to load or create users via instantiateUserSession:
1onCallbackSuccess: async ({ authProvider, tokenResponse, session, userSessionId }) =>
2 instantiateUserSession({
3 authProvider,
4 tokenResponse,
5 session,
6 userSessionId,
7 getUser: async (userIdentity) => {
8 // Find user in your database
9 return await db.users.findByAuthSub(userIdentity.sub);
10 },
11 onNewUser: async (userIdentity) => {
12 // Create new user in your database
13 return await db.users.create({
14 authSub: userIdentity.sub,
15 email: userIdentity.email,
16 name: userIdentity.name
17 });
18 }
19 })Route Configuration Props
Customize the route paths for all authentication endpoints:
| Prop | Default | Description |
|---|---|---|
authorizeRoute | /oauth2/:provider/authorization | Custom authorization route path |
callbackRoute | /oauth2/callback | Custom callback route path |
statusRoute | /oauth2/status | Custom status check route path |
signoutRoute | /oauth2/signout | Custom sign-out route path |
profileRoute | /oauth2/profile | Custom profile fetch route path |
refreshRoute | /oauth2/tokens | Custom token refresh route path |
revokeRoute | /oauth2/revocation | Custom token revocation route path |
Lifecycle Hooks
Hook into each stage of the OAuth flow for custom behavior:
| Hook | Description |
|---|---|
onAuthorizeSuccess | Called before redirecting to provider |
onAuthorizeError | Called when authorization URL generation fails |
onCallbackSuccess | Called after successful token exchange |
onCallbackError | Called when callback/token exchange fails |
onProfileSuccess | Called after successful profile fetch |
onProfileError | Called when profile fetch fails |
onStatus | Called when checking user session status |
onRefreshSuccess | Called after successful token refresh |
onRefreshError | Called when token refresh fails |
onRevocationSuccess | Called after successful token revocation |
onRevocationError | Called when token revocation fails |
onSignOut | Called before session destruction |
onSessionCleanup | Called when expired sessions are removed during cleanup |