auth

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 23, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package auth provides the core data layer for Aegis authentication system. It defines the fundamental storage interfaces and models for users, accounts, sessions, and verification tokens that form the foundation of authentication.

The package follows a repository pattern with four primary storage interfaces:

  • UserStore: Core user identity management
  • AccountStore: Provider-specific account linking (OAuth, email/password, etc.)
  • VerificationStore: Temporary tokens for email verification, password reset, etc.
  • SessionStore: Active user session tracking with token management

A default SQL-based implementation using sqlc is provided, but consumers can supply custom implementations for any store to integrate with different backends.

Example usage:

auth := auth.New(auth.Config{
	DB: db, // Uses default SQL stores for all operations
})

// Or with custom stores:
auth := auth.New(auth.Config{
	DB:        db,
	UserStore: myCustomUserStore, // Custom implementation
	// Other stores fall back to defaults
})

Package auth provides schema export functionality for different database dialects. The actual SQL schemas are embedded from internal files and can be accessed programmatically for documentation, CLI tools, or custom migration systems.

This allows users to access the core authentication schema definitions without needing to extract them from binary builds.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func PackageName

func PackageName() string

PackageName returns the package identifier for the auth schema. This is used by the CLI schema export tool.

Types

type Account

type Account struct {
	// ID is the unique identifier for this account
	ID string `json:"id"`

	// UserID links this account to a User
	UserID string `json:"userId"`

	// Provider identifies the authentication method (e.g., "credentials", "google", "github")
	Provider string `json:"provider"`

	// ProviderAccountID is the provider-specific user identifier
	// (e.g., email for credentials, OAuth provider user ID for OAuth)
	ProviderAccountID string `json:"providerAccountId"`

	// PasswordHash stores the hashed password for credential-based accounts.
	// Never returned in JSON responses (json:"-").
	PasswordHash string `json:"-"`

	// AccessToken stores the OAuth access token (OAuth providers only)
	AccessToken string `json:"accessToken,omitempty"`

	// RefreshToken stores the OAuth refresh token (OAuth providers only)
	RefreshToken string `json:"refreshToken,omitempty"`

	// ExpiresAt indicates when the access token expires (OAuth providers only)
	ExpiresAt time.Time `json:"expiresAt,omitempty"`

	// CreatedAt is when this account was created
	CreatedAt time.Time `json:"createdAt"`

	// UpdatedAt is when this account was last modified
	UpdatedAt time.Time `json:"updatedAt"`

	// Metadata stores custom JSON data for provider-specific attributes
	Metadata json.RawMessage `json:"metadata,omitempty"`
}

Account represents a provider-specific authentication account linked to a User. A single User can have multiple Accounts (e.g., one for email/password, one for Google OAuth, one for GitHub OAuth, etc.).

For credential-based auth (email/password), the ProviderAccountID is typically the email address, and PasswordHash contains the hashed password.

For OAuth providers, AccessToken and RefreshToken store the provider's tokens, and ExpiresAt tracks when the access token expires. The PasswordHash field is not used for OAuth accounts.

func (*Account) GetAccessToken

func (a *Account) GetAccessToken() string

GetAccessToken returns the OAuth access token.

func (*Account) GetCreatedAt

func (a *Account) GetCreatedAt() time.Time

GetCreatedAt returns the account creation timestamp.

func (*Account) GetExpiresAt

func (a *Account) GetExpiresAt() time.Time

GetExpiresAt returns when the OAuth access token expires.

func (*Account) GetID

func (a *Account) GetID() string

GetID returns the account's unique identifier.

func (*Account) GetPasswordHash

func (a *Account) GetPasswordHash() string

GetPasswordHash returns the hashed password (for credential-based accounts).

func (*Account) GetProvider

func (a *Account) GetProvider() string

GetProvider returns the authentication provider name.

func (*Account) GetProviderAccountID

func (a *Account) GetProviderAccountID() string

GetProviderAccountID returns the provider-specific user identifier.

func (*Account) GetRefreshToken

func (a *Account) GetRefreshToken() string

GetRefreshToken returns the OAuth refresh token.

func (*Account) GetUpdatedAt

func (a *Account) GetUpdatedAt() time.Time

GetUpdatedAt returns the account last-modified timestamp.

func (*Account) GetUserID

func (a *Account) GetUserID() string

GetUserID returns the ID of the user this account belongs to.

func (*Account) SetAccessToken

func (a *Account) SetAccessToken(s string)

SetAccessToken sets the OAuth access token.

func (*Account) SetCreatedAt

func (a *Account) SetCreatedAt(t time.Time)

SetCreatedAt sets the account creation timestamp.

func (*Account) SetExpiresAt

func (a *Account) SetExpiresAt(t time.Time)

SetExpiresAt sets when the OAuth access token expires.

func (*Account) SetID

func (a *Account) SetID(id string)

SetID sets the account's unique identifier.

func (*Account) SetPasswordHash

func (a *Account) SetPasswordHash(h string)

SetPasswordHash sets the hashed password (for credential-based accounts).

func (*Account) SetProvider

func (a *Account) SetProvider(p string)

SetProvider sets the authentication provider name.

func (*Account) SetProviderAccountID

func (a *Account) SetProviderAccountID(s string)

SetProviderAccountID sets the provider-specific user identifier.

func (*Account) SetRefreshToken

func (a *Account) SetRefreshToken(s string)

SetRefreshToken sets the OAuth refresh token.

func (*Account) SetUpdatedAt

func (a *Account) SetUpdatedAt(t time.Time)

SetUpdatedAt sets the account last-modified timestamp.

func (*Account) SetUserID

func (a *Account) SetUserID(id string)

SetUserID sets the ID of the user this account belongs to.

type AccountStore

type AccountStore interface {
	// Create persists a new account to storage.
	// Returns an error if an account with the same provider and provider
	// account ID already exists.
	Create(ctx context.Context, account Account) error

	// GetByID retrieves an account by its unique identifier.
	// Returns sql.ErrNoRows or equivalent if no account is found.
	GetByID(ctx context.Context, id string) (Account, error)

	// GetByUserID retrieves all accounts belonging to a specific user.
	// Returns an empty slice if the user has no accounts.
	GetByUserID(ctx context.Context, userID string) ([]Account, error)

	// GetByProvider retrieves an account by provider name and provider-specific user ID.
	// This is used during login to find an existing account for a provider.
	// Returns sql.ErrNoRows or equivalent if no matching account is found.
	GetByProvider(ctx context.Context, provider, providerAccountID string) (Account, error)

	// Update modifies an existing account's data (e.g., updating OAuth tokens).
	// Returns an error if the account does not exist.
	Update(ctx context.Context, account Account) error

	// Delete removes an account from storage.
	// Returns an error if the account does not exist.
	Delete(ctx context.Context, id string) error
}

AccountStore defines the interface for account storage operations. Implementations manage provider-specific authentication accounts that are linked to users.

A single user can have multiple accounts (one per authentication provider).

type Auth

type Auth struct {
	// contains filtered or unexported fields
}

Auth represents the core authentication system and provides access to all configured storage backends. It acts as a central registry for user, account, session, and verification data operations.

Auth is safe for concurrent use and should be initialized once at application startup and shared across the application.

func New

func New(cfg Config) *Auth

New creates a new Auth instance with the provided configuration. For any store that is nil in the Config, a default SQL-based implementation is automatically created using the provided database connection.

Panics if DB is nil and any store is also nil, since default stores cannot be created without a database connection.

func (*Auth) AccountStore

func (a *Auth) AccountStore() AccountStore

AccountStore returns the configured account store implementation. Use this to manage provider-specific account associations and credentials.

func (*Auth) SessionStore

func (a *Auth) SessionStore() SessionStore

SessionStore returns the configured session store implementation. Use this to manage active user sessions, including token-based and refresh token authentication flows.

func (*Auth) UserStore

func (a *Auth) UserStore() UserStore

UserStore returns the configured user store implementation. Use this to perform CRUD operations on user identities.

func (*Auth) VerificationStore

func (a *Auth) VerificationStore() VerificationStore

VerificationStore returns the configured verification store implementation. Use this to manage temporary verification tokens for email confirmation, password resets, OTP codes, and other time-limited verification flows.

type Config

type Config struct {
	// DB is the SQL database connection used for default store implementations.
	// Required if any store field is left nil.
	DB *sql.DB

	// UserStore handles user identity storage operations.
	// If nil, uses default SQL implementation.
	UserStore UserStore

	// AccountStore manages provider-linked accounts (OAuth, credentials, etc.).
	// If nil, uses default SQL implementation.
	AccountStore AccountStore

	// VerificationStore manages temporary verification tokens.
	// If nil, uses default SQL implementation.
	VerificationStore VerificationStore

	// SessionStore handles active session persistence.
	// If nil, uses default SQL implementation.
	SessionStore SessionStore
}

Config holds the configuration for the auth system. Only the User model is generic.

If any store is nil, the default SQL-based implementation will be used automatically using the provided DB connection. This allows mixing custom and default stores as needed.

type DefaultStore

type DefaultStore struct {
	// contains filtered or unexported fields
}

DefaultStore holds all default SQL-based store implementations. It provides a complete implementation of all storage interfaces using sqlc-generated database queries.

This is the standard storage backend for Aegis and supports both PostgreSQL and MySQL databases through dialect-specific SQL schemas.

func NewDefaultStore

func NewDefaultStore(db *sql.DB) *DefaultStore

NewDefaultStore creates a new default store with all SQL-based implementations. The provided database connection is used for all queries. The connection should already be configured with the appropriate driver (postgres or mysql) and the schema tables should exist (use GetMigrations to set up the schema).

func (*DefaultStore) AccountStore

func (s *DefaultStore) AccountStore() AccountStore

AccountStore returns the default account store implementation.

func (*DefaultStore) SessionStore

func (s *DefaultStore) SessionStore() SessionStore

SessionStore returns the default session store implementation.

func (*DefaultStore) UserStore

func (s *DefaultStore) UserStore() UserStore

UserStore returns the default user store implementation.

func (*DefaultStore) VerificationStore

func (s *DefaultStore) VerificationStore() VerificationStore

VerificationStore returns the default verification store implementation.

type Dependency

type Dependency struct {
	// Package is the Go import path of the dependency
	Package string

	// Version is the minimum required version of the dependency
	Version int
}

Dependency represents a schema dependency on another package.

type Dialect

type Dialect string

Dialect represents a database dialect/driver.

const (
	// DialectPostgres is for PostgreSQL databases (>=9.6 recommended)
	DialectPostgres Dialect = "postgres"

	// DialectMySQL is for MySQL databases (>=5.7 or MariaDB >=10.2)
	DialectMySQL Dialect = "mysql"

	// DialectSQLite is for SQLite databases (currently not implemented)
	DialectSQLite Dialect = "sqlite"
)

type Migration

type Migration struct {
	// Version is the numeric migration version (e.g., 1, 2, 3).
	// Version 1 is always the initial schema.
	Version int

	// Description is a human-readable summary of what this migration does
	// (e.g., "add_user_roles", "alter_session_index").
	Description string

	// Up is the SQL to apply this migration (create tables, add columns, etc.).
	Up string

	// Down is the SQL to revert this migration (drop tables, remove columns, etc.).
	Down string
}

Migration represents a versioned database schema change. Each migration has both an "up" script (to apply the change) and a "down" script (to revert it), enabling bidirectional schema evolution.

func GetMigrations

func GetMigrations(dialect Dialect) ([]Migration, error)

GetMigrations returns all migrations for the specified database dialect in version order.

Migration versioning:

  • Version 001: The initial schema from internal/sql/<dialect>/schema.sql
  • Version 002+: Additional migrations from migrations/<dialect>/*.sql

Migration file naming convention:

<version>_<description>.<up|down>.sql

Examples:

002_add_user_roles.up.sql     - Applies migration 002
002_add_user_roles.down.sql   - Reverts migration 002
003_alter_sessions.up.sql     - Applies migration 003

Each migration version must have both .up.sql and .down.sql files. Migrations are returned sorted by version number for sequential application.

Parameters:

  • dialect: The database dialect (postgres, mysql, sqlite)

Returns:

  • Slice of migrations sorted by version
  • Error if the dialect is not supported or if migration files are malformed

type Schema

type Schema struct {
	// Dialect identifies the database type (postgres, mysql, sqlite)
	Dialect Dialect

	// SQL is the complete schema definition in SQL
	SQL string

	// Info contains metadata about the schema package
	Info SchemaInfo
}

Schema represents the complete SQL schema for a specific database dialect.

func GetSchema

func GetSchema(dialect Dialect) (*Schema, error)

GetSchema returns the complete SQL schema definition for the specified dialect.

This is useful for:

  • Generating documentation
  • Initializing new databases
  • Comparing schemas across dialects
  • Custom migration tooling

The returned Schema includes both the raw SQL and metadata about the schema package.

Example:

schema, err := auth.GetSchema(auth.DialectPostgres)
if err != nil {
	log.Fatal(err)
}
fmt.Println(schema.SQL) // Prints the full PostgreSQL schema

type SchemaInfo

type SchemaInfo struct {
	// Package is the Go import path for this schema
	Package string

	// Version is the schema version number (currently unused, always 0)
	Version int

	// Description is a human-readable summary of the schema
	Description string

	// Dependencies lists other schema packages this schema depends on
	Dependencies []Dependency
}

SchemaInfo contains metadata about a schema package. This can be used for dependency tracking and versioning in complex systems.

type Session

type Session struct {
	// ID is the unique identifier for this session
	ID string `json:"id"`

	// UserID links this session to a User
	UserID string `json:"userId"`

	// Token is the session authentication token used in requests
	Token string `json:"token"`

	// RefreshToken is an optional long-lived token for obtaining new sessions
	RefreshToken string `json:"refreshToken,omitempty"`

	// ExpiresAt indicates when this session becomes invalid
	ExpiresAt time.Time `json:"expiresAt"`

	// CreatedAt is when this session was created
	CreatedAt time.Time `json:"createdAt"`

	// IPAddress of the client that created this session
	IPAddress string `json:"ipAddress,omitempty"`

	// UserAgent of the client that created this session
	UserAgent string `json:"userAgent,omitempty"`

	// Metadata stores custom JSON data for session-specific attributes
	Metadata json.RawMessage `json:"metadata,omitempty"`
}

Session represents an active user session in the authentication system. Sessions track authenticated user activity and enable stateful authentication through session tokens and optional refresh tokens.

Sessions have a limited lifetime defined by ExpiresAt. When a session expires, users must re-authenticate unless a refresh token flow is implemented to generate new sessions.

IPAddress and UserAgent are captured for security auditing and can be used to detect suspicious activity or allow users to review active sessions.

func (*Session) GetExpiresAt

func (s *Session) GetExpiresAt() time.Time

GetExpiresAt returns the session expiration timestamp.

func (*Session) GetID

func (s *Session) GetID() string

GetID returns the session's unique identifier.

func (*Session) GetRefreshToken

func (s *Session) GetRefreshToken() string

GetRefreshToken returns the optional refresh token.

func (*Session) GetToken

func (s *Session) GetToken() string

GetToken returns the session authentication token.

func (*Session) GetUserID

func (s *Session) GetUserID() string

GetUserID returns the ID of the user this session belongs to.

func (*Session) SetCreatedAt

func (s *Session) SetCreatedAt(t time.Time)

SetCreatedAt sets the session creation timestamp.

func (*Session) SetExpiresAt

func (s *Session) SetExpiresAt(t time.Time)

SetExpiresAt sets the session expiration timestamp.

func (*Session) SetID

func (s *Session) SetID(id string)

SetID sets the session's unique identifier.

func (*Session) SetIPAddress

func (s *Session) SetIPAddress(ip string)

SetIPAddress sets the client IP address that created this session.

func (*Session) SetRefreshToken

func (s *Session) SetRefreshToken(r string)

SetRefreshToken sets the optional refresh token.

func (*Session) SetToken

func (s *Session) SetToken(t string)

SetToken sets the session authentication token.

func (*Session) SetUserAgent

func (s *Session) SetUserAgent(ua string)

SetUserAgent sets the client user agent that created this session.

func (*Session) SetUserID

func (s *Session) SetUserID(id string)

SetUserID sets the ID of the user this session belongs to.

type SessionStore

type SessionStore interface {
	// Create persists a new session to storage.
	Create(ctx context.Context, session Session) error

	// Get retrieves a session by its unique identifier.
	// Returns sql.ErrNoRows or equivalent if no session is found.
	Get(ctx context.Context, id string) (Session, error)

	// GetByToken retrieves a session by its authentication token.
	// This is the primary method used during request authentication.
	// Returns sql.ErrNoRows or equivalent if no session is found.
	GetByToken(ctx context.Context, token string) (Session, error)

	// GetByRefreshToken retrieves a session by its refresh token.
	// Used in refresh token flows to generate new sessions.
	// Returns sql.ErrNoRows or equivalent if no session is found.
	GetByRefreshToken(ctx context.Context, refreshToken string) (Session, error)

	// GetByUserID retrieves all active sessions for a specific user.
	// Returns an empty slice if the user has no active sessions.
	GetByUserID(ctx context.Context, userID string) ([]Session, error)

	// Update modifies an existing session's data (e.g., extending expiration).
	// Returns an error if the session does not exist.
	Update(ctx context.Context, session Session) error

	// Delete removes a specific session (used during logout).
	Delete(ctx context.Context, id string) error

	// DeleteByUserID removes all sessions for a user (used during password change
	// or when forcing all sessions to be logged out).
	DeleteByUserID(ctx context.Context, userID string) error

	// CleanupExpired removes all expired sessions.
	// This should be called periodically to prevent storage bloat.
	CleanupExpired(ctx context.Context) error
}

SessionStore defines the interface for session storage operations. Implementations manage active user sessions and their authentication tokens.

type User

type User struct {
	// ID is the unique identifier for this user (typically a ULID or UUID)
	ID string `json:"id"`

	// Avatar is the URL to the user's profile picture
	Avatar string `json:"avatar,omitempty"`

	// Name is the user's display name
	Name string `json:"name,omitempty"`

	// Email is the user's email address (optional for OAuth-only users)
	Email string `json:"email,omitempty"`

	// CreatedAt is when the user account was created
	CreatedAt time.Time `json:"createdAt"`

	// UpdatedAt is when the user account was last modified
	UpdatedAt time.Time `json:"updatedAt"`

	// Disabled indicates if the user account has been deactivated
	Disabled bool `json:"disabled"`

	// Metadata stores custom JSON data for application-specific attributes
	Metadata json.RawMessage `json:"metadata,omitempty"`
}

User represents the core user identity model in the authentication system. This is the primary entity that represents a person or service using the application.

Users can have multiple Accounts (one per authentication provider) but maintain a single unified identity. The Email field is optional to support OAuth-only users who may not provide an email address.

The Metadata field allows storing arbitrary JSON data for application-specific user attributes without requiring schema changes.

func (*User) GetEmail

func (u *User) GetEmail() string

GetEmail returns the user's email address.

func (*User) GetID

func (u *User) GetID() string

GetID returns the user's unique identifier.

func (*User) GetName

func (u *User) GetName() string

GetName returns the user's display name.

func (*User) SetCreatedAt

func (u *User) SetCreatedAt(t time.Time)

SetCreatedAt sets the user creation timestamp.

func (*User) SetEmail

func (u *User) SetEmail(email string)

SetEmail sets the user's email address.

func (*User) SetID

func (u *User) SetID(id string)

SetID sets the user's unique identifier.

func (*User) SetName

func (u *User) SetName(name string)

SetName sets the user's display name.

func (*User) SetUpdatedAt

func (u *User) SetUpdatedAt(t time.Time)

SetUpdatedAt sets the user last-modified timestamp.

type UserStore

type UserStore interface {
	// Create persists a new user to storage.
	// Returns the created user with any storage-assigned fields populated.
	// Returns an error if a user with the same email already exists.
	Create(ctx context.Context, user User) (User, error)

	// GetByEmail retrieves a user by their email address.
	// Returns sql.ErrNoRows or equivalent if no user is found.
	GetByEmail(ctx context.Context, email string) (User, error)

	// GetByID retrieves a user by their unique identifier.
	// Returns sql.ErrNoRows or equivalent if no user is found.
	GetByID(ctx context.Context, id string) (User, error)

	// Update modifies an existing user's data.
	// Returns an error if the user does not exist.
	Update(ctx context.Context, user User) error

	// Delete removes a user from storage (may be soft or hard delete).
	// Returns an error if the user does not exist.
	Delete(ctx context.Context, id string) error

	// List retrieves a paginated list of users.
	// The offset and limit parameters control pagination.
	List(ctx context.Context, offset, limit int) ([]User, error)

	// Count returns the total number of users in storage.
	Count(ctx context.Context) (int, error)
}

UserStore defines the interface for user storage operations. Implementations of this interface manage the persistence and retrieval of user identity data.

All methods accept a context for cancellation and deadline support. Implementations should respect context cancellation and return context.Canceled or context.DeadlineExceeded when appropriate.

type Verification

type Verification struct {
	// ID is the unique identifier for this verification
	ID string `json:"id"`

	// Identifier is the target of verification (e.g., email address, phone number)
	Identifier string `json:"identifier"`

	// Token is the secret verification code or token
	Token string `json:"token"`

	// Type categorizes the verification purpose (e.g., "email", "reset", "otp")
	Type string `json:"type"`

	// ExpiresAt indicates when this verification token expires
	ExpiresAt time.Time `json:"expiresAt"`

	// CreatedAt is when this verification was created
	CreatedAt time.Time `json:"createdAt"`

	// Metadata stores custom JSON data for verification-specific attributes
	Metadata json.RawMessage `json:"metadata,omitempty"`
}

Verification represents a temporary verification token used for various authentication flows such as email verification, password reset, OTP codes, magic links, and other time-limited verification mechanisms.

The Type field distinguishes between different verification purposes (e.g., "email", "reset", "otp").

Verifications are always temporary and should be deleted after use or after they expire.

func (*Verification) GetCreatedAt

func (v *Verification) GetCreatedAt() time.Time

GetCreatedAt returns the verification creation timestamp.

func (*Verification) GetExpiresAt

func (v *Verification) GetExpiresAt() time.Time

GetExpiresAt returns the verification expiration timestamp.

func (*Verification) GetID

func (v *Verification) GetID() string

GetID returns the verification's unique identifier.

func (*Verification) GetIdentifier

func (v *Verification) GetIdentifier() string

GetIdentifier returns the target identifier being verified.

func (*Verification) GetToken

func (v *Verification) GetToken() string

GetToken returns the secret verification token.

func (*Verification) SetCreatedAt

func (v *Verification) SetCreatedAt(t time.Time)

SetCreatedAt sets the verification creation timestamp.

func (*Verification) SetExpiresAt

func (v *Verification) SetExpiresAt(t time.Time)

SetExpiresAt sets the verification expiration timestamp.

func (*Verification) SetID

func (v *Verification) SetID(id string)

SetID sets the verification's unique identifier.

func (*Verification) SetIdentifier

func (v *Verification) SetIdentifier(i string)

SetIdentifier sets the target identifier being verified.

func (*Verification) SetToken

func (v *Verification) SetToken(t string)

SetToken sets the secret verification token.

type VerificationStore

type VerificationStore interface {
	// Create persists a new verification token to storage.
	Create(ctx context.Context, verification Verification) error

	// GetByToken retrieves a verification by its token value.
	// Returns sql.ErrNoRows or equivalent if no verification is found.
	GetByToken(ctx context.Context, token string) (Verification, error)

	// GetByIdentifier retrieves all verifications for a given identifier
	// (e.g., all pending verifications for an email address).
	// Returns an empty slice if no verifications exist for the identifier.
	GetByIdentifier(ctx context.Context, identifier string) ([]Verification, error)

	// InvalidateByIdentifier marks all verifications of a specific type for an
	// identifier as invalid/used. This is typically called after successful
	// verification to prevent token reuse.
	InvalidateByIdentifier(ctx context.Context, identifier, vType string) error

	// Delete removes a verification token from storage.
	Delete(ctx context.Context, id string) error

	// CleanupExpired removes all expired verification tokens.
	// This should be called periodically to prevent storage bloat.
	CleanupExpired(ctx context.Context) error
}

VerificationStore defines the interface for verification token storage operations. Implementations manage temporary tokens used for email verification, password resets, OTP codes, and other time-limited verification flows.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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