extension

package
v0.0.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 4, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

README

AuthSome Forge Extension

The easiest way to integrate AuthSome into your Forge application.

Quick Start

1. Basic Setup
package main

import (
    "github.com/xraph/forge"
    forgedb "github.com/xraph/forge/extensions/database"
    authext "github.com/xraph/authsome/extension"
)

func main() {
    // Create Forge app
    app := forge.NewApp(forge.AppConfig{
        Name:        "myapp",
        Environment: "development",
        HTTPAddress: ":8080",
    })

    // Register database extension
    app.RegisterExtension(forgedb.NewExtension(
        forgedb.WithDatabase(forgedb.DatabaseConfig{
            Name: "default",
            Type: forgedb.TypeSQLite,
            DSN:  "myapp.db",
        }),
    ))

    // Register AuthSome extension - that's it!
    app.RegisterExtension(authext.NewExtension())

    // Start the app
    app.Run()
}

That's all you need! AuthSome will:

  • ✅ Auto-discover the database
  • ✅ Initialize all services
  • ✅ Mount routes at /api/auth
  • ✅ Register all services in DI

Configuration

Programmatic Configuration
import (
    authext "github.com/xraph/authsome/extension"
    "github.com/xraph/authsome"
)

app.RegisterExtension(authext.NewExtension(
    authext.WithMode(authsome.ModeSaaS),
    authext.WithBasePath("/auth"),
    authext.WithSecret("your-secret-key"),
    authext.WithRBACEnforcement(true),
))
YAML Configuration
# config.yaml
authsome:
  mode: saas
  basePath: /auth
  secret: ${SECRET_KEY}
  rbacEnforce: true
  trustedOrigins:
    - https://example.com
    - https://app.example.com
  databaseName: auth_db  # Use specific database from DatabaseManager
  security:
    enabled: true
    ipWhitelist:
      - 192.168.1.0/24
  rateLimit:
    enabled: true
    default:
      limit: 100
      window: 60
// Load config automatically from file
app := forge.NewApp(forge.AppConfig{
    ConfigFile: "config.yaml",
})

// Extension will load config automatically
app.RegisterExtension(authext.NewExtension())

With Plugins

import (
    authext "github.com/xraph/authsome/extension"
    "github.com/xraph/authsome/plugins/jwt"
    "github.com/xraph/authsome/plugins/apikey"
    "github.com/xraph/authsome/plugins/dashboard"
)

// Method 1: During extension creation
app.RegisterExtension(authext.NewExtension(
    authext.WithPlugins(
        jwt.NewPlugin(),
        apikey.NewPlugin(),
        dashboard.NewPlugin(),
    ),
))

// Method 2: After extension creation
authExt := authext.NewExtension()
authExt.RegisterPlugin(jwt.NewPlugin())
authExt.RegisterPlugin(apikey.NewPlugin())
app.RegisterExtension(authExt)

Configuration Options

Mode
authext.WithMode(authsome.ModeStandalone)  // Single tenant
authext.WithMode(authsome.ModeSaaS)        // Multi-tenant
Database
// Option 1: Auto-resolve from Forge database extension (default)
authext.NewExtension()

// Option 2: Use specific database from DatabaseManager
authext.NewExtension(
    authext.WithDatabaseName("auth_db"),
)

// Option 3: Provide database directly
db := bun.NewDB(...)
authext.NewExtension(
    authext.WithDatabase(db),
)
Security
authext.NewExtension(
    authext.WithSecurityConfig(security.Config{
        Enabled: true,
        IPWhitelist: []string{"192.168.1.0/24"},
        AllowedCountries: []string{"US", "CA"},
    }),
    authext.WithGeoIPProvider(myGeoIPProvider),
)
Rate Limiting
authext.NewExtension(
    authext.WithRateLimitConfig(ratelimit.Config{
        Enabled: true,
        Default: ratelimit.Rule{
            Limit:  100,
            Window: 60,
        },
    }),
    authext.WithRateLimitStorage(redisStorage),
)

Accessing AuthSome

From Extension Instance
authExt := authext.NewExtension()
app.RegisterExtension(authExt)

// Start app
app.Start(context.Background())

// Access AuthSome instance
auth := authExt.Auth()
userService := auth.GetServiceRegistry().UserService()
From Forge DI Container
import "github.com/xraph/authsome"

// Resolve services from container
userService, _ := authsome.ResolveUserService(app.Container())
sessionService, _ := authsome.ResolveSessionService(app.Container())
authService, _ := authsome.ResolveAuthService(app.Container())

Complete Example

package main

import (
    "context"
    "log"

    "github.com/xraph/forge"
    forgedb "github.com/xraph/forge/extensions/database"
    authext "github.com/xraph/authsome/extension"
    "github.com/xraph/authsome"
    "github.com/xraph/authsome/plugins/jwt"
    "github.com/xraph/authsome/plugins/apikey"
    "github.com/xraph/authsome/plugins/dashboard"
)

func main() {
    // Create app
    app := forge.NewApp(forge.AppConfig{
        Name:        "myapp",
        Environment: "production",
        HTTPAddress: ":8080",
        ConfigFile:  "config.yaml",
    })

    // Database extension
    app.RegisterExtension(forgedb.NewExtension(
        forgedb.WithDatabase(forgedb.DatabaseConfig{
            Name: "main",
            Type: forgedb.TypePostgres,
            DSN:  "postgres://localhost/myapp",
        }),
    ))

    // AuthSome extension with full configuration
    app.RegisterExtension(authext.NewExtension(
        authext.WithMode(authsome.ModeSaaS),
        authext.WithBasePath("/auth"),
        authext.WithSecret("your-secret-key"),
        authext.WithRBACEnforcement(true),
        authext.WithPlugins(
            jwt.NewPlugin(),
            apikey.NewPlugin(),
            dashboard.NewPlugin(),
        ),
    ))

    // Add your app routes
    app.Router().GET("/", func(c forge.Context) error {
        return c.JSON(200, map[string]string{
            "message": "Hello World",
        })
    })

    // Run
    if err := app.Run(); err != nil {
        log.Fatal(err)
    }
}

Multi-Database Example

// config.yaml
database:
  databases:
    - name: "main"
      type: "postgres"
      dsn: "postgres://localhost/app_db"
    - name: "auth"
      type: "postgres"
      dsn: "postgres://localhost/auth_db"
    - name: "analytics"
      type: "postgres"
      dsn: "postgres://localhost/analytics_db"

authsome:
  databaseName: "auth"  # Use dedicated auth database

// main.go
app.RegisterExtension(forgedb.NewExtension())
app.RegisterExtension(authext.NewExtension())

// AuthSome uses "auth" database
// Your app can use "main" or "analytics" databases

Benefits

vs Direct AuthSome Usage
Feature Direct Usage Extension
Setup Code ~30 lines ~3 lines
Database Setup Manual Automatic
Route Mounting Manual Automatic
Configuration Code-based YAML + Code
Lifecycle Manual Managed
Health Checks Manual Built-in
Extension Benefits

One-line integration - Just register the extension ✅ Auto-configuration - Loads from YAML automatically ✅ Managed lifecycle - Start/Stop/Health handled by Forge ✅ DI Integration - All services registered automatically ✅ Database auto-discovery - Works with Forge database extension ✅ Plugin support - Easy plugin registration ✅ Production ready - Proper error handling and logging

Advanced Usage

Custom Initialization
authExt := authext.NewExtension()
app.RegisterExtension(authExt)

// Start app
app.Start(context.Background())

// Access and customize after initialization
auth := authExt.Auth()

// Add custom middleware
app.Router().Use(func(next func(forge.Context) error) func(forge.Context) error {
    return func(c forge.Context) error {
        // Custom logic
        return next(c)
    }
})
Dynamic Plugin Registration
authExt := authext.NewExtension()

// Register plugins conditionally
if os.Getenv("ENABLE_JWT") == "true" {
    authExt.RegisterPlugin(jwt.NewPlugin())
}

if os.Getenv("ENABLE_DASHBOARD") == "true" {
    authExt.RegisterPlugin(dashboard.NewPlugin())
}

app.RegisterExtension(authExt)
Health Checks

The extension automatically implements Forge's health check interface:

curl http://localhost:8080/health
{
  "status": "healthy",
  "extensions": {
    "authsome": {
      "status": "healthy"
    }
  }
}

Migration from Direct Usage

Before (Direct Usage)
// 30+ lines of setup code
db := bun.NewDB(...)
auth := authsome.New(
    authsome.WithDatabase(db),
    authsome.WithForgeApp(app),
    authsome.WithMode(authsome.ModeStandalone),
    // ... more options
)
auth.Initialize(ctx)
auth.Mount(app.Router(), "/api/auth")
After (Extension)
// 1 line
app.RegisterExtension(authext.NewExtension())

Best Practices

  1. Use YAML Config for environment-specific settings
  2. Use Programmatic Options for code-driven configuration
  3. Register Plugins during extension creation for clarity
  4. Use DatabaseManager for multi-database scenarios
  5. Access via DI for loose coupling in your handlers

See Also

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ResolveAuth

func ResolveAuth(app forge.App) (*authsome.Auth, error)

ResolveAuth resolves the AuthSome instance from a Forge app Note: This only works after the app has been started

Types

type Config

type Config struct {
	// RequireEmailVerified requires email verification for all users
	RequireEmailVerified bool `yaml:"requireEmailVerified" json:"requireEmailVerified"`

	// DisableOpenAPI disables the OpenAPI documentation
	DisableOpenAPI bool `yaml:"disableOpenAPI" json:"disableOpenAPI"`

	// BasePath is the base path where auth routes are mounted
	BasePath string `yaml:"basePath" json:"basePath"`

	// Database configuration - mutually exclusive options
	// Database is a direct database connection (takes precedence)
	Database interface{} `yaml:"-" json:"-"`
	// DatabaseName is the name of the database to use from DatabaseManager
	DatabaseName string `yaml:"databaseName" json:"databaseName"`

	// CORS configuration
	CORSEnabled    bool     `yaml:"corsEnabled" json:"corsEnabled"`
	TrustedOrigins []string `yaml:"trustedOrigins" json:"trustedOrigins"`

	// Secret for signing tokens
	Secret string `yaml:"secret" json:"secret"`

	// RBACEnforce enables handler-level RBAC enforcement
	RBACEnforce bool `yaml:"rbacEnforce" json:"rbacEnforce"`

	// SecurityConfig for IP/country restrictions
	SecurityConfig *security.Config `yaml:"security" json:"security"`

	// RateLimitConfig for rate limiting
	RateLimitConfig *ratelimit.Config `yaml:"rateLimit" json:"rateLimit"`

	// RateLimitStorage is the storage backend for rate limiting
	RateLimitStorage ratelimit.Storage `yaml:"-" json:"-"`

	// GeoIPProvider for country-based restrictions
	GeoIPProvider security.GeoIPProvider `yaml:"-" json:"-"`

	// SessionCookie configures cookie-based session management
	SessionCookie *session.CookieConfig `yaml:"sessionCookie" json:"sessionCookie"`

	// SessionConfig configures session behavior (TTL, sliding window, refresh tokens)
	SessionConfig *session.Config `yaml:"sessionConfig" json:"sessionConfig"`

	// UserConfig configures user service behavior (password requirements, etc.)
	UserConfig *user.Config `yaml:"userConfig" json:"userConfig"`

	// AuthMiddlewareConfig configures the authentication middleware behavior
	AuthMiddlewareConfig *middleware.AuthMiddlewareConfig `yaml:"authMiddleware" json:"authMiddleware"`

	// Plugins to register with AuthSome
	Plugins []plugins.Plugin `yaml:"-" json:"-"`

	// RequireConfig determines if configuration must be loaded from file
	RequireConfig bool `yaml:"-" json:"-"`
}

Config holds the configuration for the AuthSome extension

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default configuration

type ConfigOption

type ConfigOption func(*Config)

ConfigOption is a functional option for configuring the extension

func WithAuthMiddlewareConfig added in v0.0.2

func WithAuthMiddlewareConfig(config middleware.AuthMiddlewareConfig) ConfigOption

WithAuthMiddlewareConfig sets the authentication middleware configuration This controls how the global authentication middleware behaves, including: - Session cookie name - Optional authentication (allow unauthenticated requests) - API key authentication settings - Context resolution (app/environment from headers or API key)

Example:

WithAuthMiddlewareConfig(middleware.AuthMiddlewareConfig{
    SessionCookieName:   "my_session",
    Optional:            true,
    AllowAPIKeyInQuery:  false, // Security best practice
    AllowSessionInQuery: false, // Security best practice
    Context: middleware.ContextConfig{
        AutoDetectFromAPIKey: true,
        AutoDetectFromConfig: true,
    },
})

func WithBasePath

func WithBasePath(path string) ConfigOption

WithBasePath sets the base path for routes

func WithCORSEnabled added in v0.0.2

func WithCORSEnabled(enabled bool) ConfigOption

WithCORSEnabled enables or disables CORS middleware

func WithConfig

func WithConfig(config Config) ConfigOption

WithConfig sets the entire configuration

func WithDatabase

func WithDatabase(db *bun.DB) ConfigOption

WithDatabase sets a direct database connection

func WithDatabaseName

func WithDatabaseName(name string) ConfigOption

WithDatabaseName sets the database name to use from DatabaseManager

func WithDisableOpenAPI added in v0.0.2

func WithDisableOpenAPI(disable bool) ConfigOption

func WithGeoIPProvider

func WithGeoIPProvider(provider security.GeoIPProvider) ConfigOption

WithGeoIPProvider sets the GeoIP provider

func WithGlobalCookieConfig added in v0.0.2

func WithGlobalCookieConfig(config session.CookieConfig) ConfigOption

WithGlobalCookieConfig sets the global cookie configuration for session management This configuration applies to all apps unless overridden at the app level Example:

WithGlobalCookieConfig(session.CookieConfig{
    Enabled:  true,
    Name:     "my_session",
    HttpOnly: true,
    SameSite: "Lax",
})

func WithMinPasswordLength added in v0.0.3

func WithMinPasswordLength(length int) ConfigOption

WithMinPasswordLength sets the minimum password length

Example:

extension.WithMinPasswordLength(12)

func WithPasswordPolicy added in v0.0.3

func WithPasswordPolicy(policy string) ConfigOption

WithPasswordPolicy is a convenience function to set common password policies Predefined policies: "weak", "medium", "strong", "enterprise"

Example:

extension.WithPasswordPolicy("strong")

func WithPasswordRequirements added in v0.0.3

func WithPasswordRequirements(reqs validator.PasswordRequirements) ConfigOption

WithPasswordRequirements sets the password requirements This controls password validation for user registration and password changes

Example:

extension.WithPasswordRequirements(validator.PasswordRequirements{
    MinLength:      12,
    RequireUpper:   true,
    RequireLower:   true,
    RequireNumber:  true,
    RequireSpecial: true,
})

func WithPlugins

func WithPlugins(plugins ...plugins.Plugin) ConfigOption

WithPlugins sets the plugins to register

func WithRBACEnforcement

func WithRBACEnforcement(enabled bool) ConfigOption

WithRBACEnforcement enables/disables RBAC enforcement

func WithRateLimitConfig

func WithRateLimitConfig(config ratelimit.Config) ConfigOption

WithRateLimitConfig sets rate limit configuration

func WithRateLimitStorage

func WithRateLimitStorage(storage ratelimit.Storage) ConfigOption

WithRateLimitStorage sets the rate limit storage backend

func WithRefreshTokens added in v0.0.3

func WithRefreshTokens(enabled bool, accessTTL, refreshTTL time.Duration) ConfigOption

WithRefreshTokens enables the refresh token pattern Short-lived access tokens are issued with long-lived refresh tokens Clients must explicitly refresh when access token expires

Example:

extension.WithRefreshTokens(true, 15*time.Minute, 30*24*time.Hour)
// 15 min access tokens, 30 day refresh tokens

func WithRequireConfig

func WithRequireConfig(require bool) ConfigOption

WithRequireConfig sets whether configuration must be loaded from file

func WithRequireEmailVerification added in v0.0.7

func WithRequireEmailVerification(require bool) ConfigOption

func WithSecret

func WithSecret(secret string) ConfigOption

WithSecret sets the secret for token signing

func WithSecurityConfig

func WithSecurityConfig(config security.Config) ConfigOption

WithSecurityConfig sets security configuration

func WithSessionConfig added in v0.0.3

func WithSessionConfig(config session.Config) ConfigOption

WithSessionConfig sets the full session configuration This controls session behavior including TTL, sliding window, and refresh tokens

Example:

extension.WithSessionConfig(session.Config{
    DefaultTTL:           24 * time.Hour,
    RememberTTL:          7 * 24 * time.Hour,
    EnableSlidingWindow:  true,
    SlidingRenewalAfter:  5 * time.Minute,
    EnableRefreshTokens:  true,
    RefreshTokenTTL:      30 * 24 * time.Hour,
    AccessTokenTTL:       15 * time.Minute,
})

func WithSessionCookieEnabled added in v0.0.2

func WithSessionCookieEnabled(enabled bool) ConfigOption

WithSessionCookieEnabled enables or disables cookie-based session management globally When enabled, authentication responses will automatically set secure HTTP cookies

func WithSessionCookieMaxAge added in v0.0.3

func WithSessionCookieMaxAge(seconds int) ConfigOption

WithSessionCookieMaxAge sets the cookie MaxAge in seconds This controls how long the browser keeps the cookie If not set, defaults to session TTL (24 hours)

Example:

extension.WithSessionCookieMaxAge(3600)  // 1 hour
extension.WithSessionCookieMaxAge(86400) // 24 hours

func WithSessionCookieName added in v0.0.2

func WithSessionCookieName(name string) ConfigOption

WithSessionCookieName sets the session cookie name Default: "authsome_session"

func WithSessionTTL added in v0.0.3

func WithSessionTTL(defaultTTL, rememberTTL time.Duration) ConfigOption

WithSessionTTL sets the default and "remember me" session TTL

Example:

extension.WithSessionTTL(24*time.Hour, 7*24*time.Hour)

func WithSlidingWindowSessions added in v0.0.3

func WithSlidingWindowSessions(enabled bool, renewalThreshold ...time.Duration) ConfigOption

WithSlidingWindowSessions enables automatic session renewal on each request When enabled, sessions are extended whenever the user makes a request The renewalThreshold determines how often to actually update the database (default: 5 minutes) This prevents logging out active users while minimizing database writes

Example:

extension.WithSlidingWindowSessions(true, 5*time.Minute)

func WithTrustedOrigins

func WithTrustedOrigins(origins []string) ConfigOption

WithTrustedOrigins sets trusted origins for CORS and auto-enables CORS if origins provided

func WithUserConfig added in v0.0.3

func WithUserConfig(config user.Config) ConfigOption

WithUserConfig sets the full user configuration This controls user service behavior including password requirements

Example:

extension.WithUserConfig(user.Config{
    PasswordRequirements: validator.PasswordRequirements{
        MinLength:      12,
        RequireUpper:   true,
        RequireLower:   true,
        RequireNumber:  true,
        RequireSpecial: true,
    },
})

type Extension

type Extension struct {
	*forge.BaseExtension
	// contains filtered or unexported fields
}

Extension implements the Forge extension interface for AuthSome

func NewExtension

func NewExtension(opts ...ConfigOption) *Extension

NewExtension creates a new AuthSome extension with optional configuration

func ResolveExtension

func ResolveExtension(app forge.App) (*Extension, error)

ResolveExtension resolves the AuthSome extension from a Forge app This allows you to access the extension instance after registration

func (*Extension) Auth

func (e *Extension) Auth() *authsome.Auth

Auth returns the AuthSome instance Use this to access AuthSome programmatically after extension is registered

func (*Extension) ExcludeFromSchemas added in v0.0.2

func (e *Extension) ExcludeFromSchemas() bool

func (*Extension) GetBasePath

func (e *Extension) GetBasePath() string

GetBasePath returns the configured base path This is used by plugins to construct URLs

func (*Extension) GetDB

func (e *Extension) GetDB() *bun.DB

GetDB returns the database instance This is used by plugins that need direct database access

func (*Extension) GetPluginRegistry

func (e *Extension) GetPluginRegistry() plugins.PluginRegistry

GetPluginRegistry returns the plugin registry for plugin detection This is used by the dashboard plugin to detect which plugins are enabled

func (*Extension) GetServiceRegistry

func (e *Extension) GetServiceRegistry() *registry.ServiceRegistry

GetServiceRegistry returns the service registry This is used by plugins that need access to core services

func (*Extension) Health

func (e *Extension) Health(ctx context.Context) error

Health checks the extension health

func (*Extension) Register

func (e *Extension) Register(app forge.App) error

Register registers the extension with the Forge application

func (*Extension) RegisterPlugin

func (e *Extension) RegisterPlugin(plugin plugins.Plugin) error

RegisterPlugin registers a plugin before Start is called

func (*Extension) Start

func (e *Extension) Start(ctx context.Context) error

Start starts the extension and initializes AuthSome

func (*Extension) Stop

func (e *Extension) Stop(ctx context.Context) error

Stop stops the extension

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL