@dunx/auth

Better Auth for dunx: its handler mounted on Bun.serve, a session guard reading @Public() and @Roles(), the caller in async context, and Bun.password hashing

@dunx/auth
@dunx/auth/drizzle

Better Auth for dunx.

This package connects better-auth to dunx. It gives you a module that builds the better-auth instance from your ConfigService, five routes that mount its handler, a guard that respects @dunx/http's @Public() and @Roles(), and two adapters that run better-auth on Bun's own APIs.

better-auth handles authentication itself; this package does not reimplement it.

There is no dunx sign-in flow, no dunx session table and no dunx OAuth. Each is a better-auth feature reached through AuthModule.forRoot's options, which are better-auth's BetterAuthOptions.

Usage

TS
import { AuthModule, SessionGuard } from '@dunx/auth';
import { drizzleDatabase } from '@dunx/auth/drizzle';
import { Module } from '@dunx/core';
import { HttpFactory } from '@dunx/http';
import { DbConnection } from '@dunx/infra/db';

@Module({
  imports: [
    AuthModule.forRootAsync({
      imports: [DatabaseModule],
      inject: [AppConfigService, DbConnection],
      useFactory: (config: AppConfigService, connection: DbConnection) => ({
        secret: config.get('auth').secret,
        basePath: '/api/auth',
        database: drizzleDatabase(connection),
        emailAndPassword: { enabled: true },
      }),
    }),
  ],
})
export class AuthFeatureModule {}

// Globally, and opt routes out with @Public():
HttpFactory.create(AppModule, { middleware: [SessionGuard] });

What is here

The Authentication guide is canonical.

ExportWhat it does
AuthModuleBuilds the instance, mounts the handler, binds the guard
AuthThe better-auth instance, injectable
SessionGuardAuthenticates, honours @Public() and @Roles()
AuthContextThe authenticated caller, anywhere in the request
betterAuthDocumentbetter-auth's own paths merged into the OpenAPI document
bunPasswordBun.password native bcrypt, applied by default
@dunx/auth/drizzlebetter-auth over the connection the app already opened
redisStoragesecondaryStorage over Bun.RedisClient

Notes

  • dunx does not ship a schema for better-auth's tables, because better-auth owns them and they change with its plugins. Generate them with bunx @better-auth/cli generate, and export them under the singular model names the adapter looks up.
  • Under setGlobalPrefix, basePath is what better-auth matches. mountAt is where the route is mounted. Omitting mountAt with a non-default basePath is a boot error.
  • AuthContext is a second AsyncLocalStorage store rather than a key in RequestContext. Everything in that store is serialized into every log line the request writes.