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 ¶
- func PackageName() string
- type Account
- func (a *Account) GetAccessToken() string
- func (a *Account) GetCreatedAt() time.Time
- func (a *Account) GetExpiresAt() time.Time
- func (a *Account) GetID() string
- func (a *Account) GetPasswordHash() string
- func (a *Account) GetProvider() string
- func (a *Account) GetProviderAccountID() string
- func (a *Account) GetRefreshToken() string
- func (a *Account) GetUpdatedAt() time.Time
- func (a *Account) GetUserID() string
- func (a *Account) SetAccessToken(s string)
- func (a *Account) SetCreatedAt(t time.Time)
- func (a *Account) SetExpiresAt(t time.Time)
- func (a *Account) SetID(id string)
- func (a *Account) SetPasswordHash(h string)
- func (a *Account) SetProvider(p string)
- func (a *Account) SetProviderAccountID(s string)
- func (a *Account) SetRefreshToken(s string)
- func (a *Account) SetUpdatedAt(t time.Time)
- func (a *Account) SetUserID(id string)
- type AccountStore
- type Auth
- type Config
- type DefaultStore
- type Dependency
- type Dialect
- type Migration
- type Schema
- type SchemaInfo
- type Session
- func (s *Session) GetExpiresAt() time.Time
- func (s *Session) GetID() string
- func (s *Session) GetRefreshToken() string
- func (s *Session) GetToken() string
- func (s *Session) GetUserID() string
- func (s *Session) SetCreatedAt(t time.Time)
- func (s *Session) SetExpiresAt(t time.Time)
- func (s *Session) SetID(id string)
- func (s *Session) SetIPAddress(ip string)
- func (s *Session) SetRefreshToken(r string)
- func (s *Session) SetToken(t string)
- func (s *Session) SetUserAgent(ua string)
- func (s *Session) SetUserID(id string)
- type SessionStore
- type User
- type UserStore
- type Verification
- func (v *Verification) GetCreatedAt() time.Time
- func (v *Verification) GetExpiresAt() time.Time
- func (v *Verification) GetID() string
- func (v *Verification) GetIdentifier() string
- func (v *Verification) GetToken() string
- func (v *Verification) SetCreatedAt(t time.Time)
- func (v *Verification) SetExpiresAt(t time.Time)
- func (v *Verification) SetID(id string)
- func (v *Verification) SetIdentifier(i string)
- func (v *Verification) SetToken(t string)
- type VerificationStore
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 ¶
GetAccessToken returns the OAuth access token.
func (*Account) GetCreatedAt ¶
GetCreatedAt returns the account creation timestamp.
func (*Account) GetExpiresAt ¶
GetExpiresAt returns when the OAuth access token expires.
func (*Account) GetPasswordHash ¶
GetPasswordHash returns the hashed password (for credential-based accounts).
func (*Account) GetProvider ¶
GetProvider returns the authentication provider name.
func (*Account) GetProviderAccountID ¶
GetProviderAccountID returns the provider-specific user identifier.
func (*Account) GetRefreshToken ¶
GetRefreshToken returns the OAuth refresh token.
func (*Account) GetUpdatedAt ¶
GetUpdatedAt returns the account last-modified timestamp.
func (*Account) SetAccessToken ¶
SetAccessToken sets the OAuth access token.
func (*Account) SetCreatedAt ¶
SetCreatedAt sets the account creation timestamp.
func (*Account) SetExpiresAt ¶
SetExpiresAt sets when the OAuth access token expires.
func (*Account) SetPasswordHash ¶
SetPasswordHash sets the hashed password (for credential-based accounts).
func (*Account) SetProvider ¶
SetProvider sets the authentication provider name.
func (*Account) SetProviderAccountID ¶
SetProviderAccountID sets the provider-specific user identifier.
func (*Account) SetRefreshToken ¶
SetRefreshToken sets the OAuth refresh token.
func (*Account) SetUpdatedAt ¶
SetUpdatedAt sets the account last-modified timestamp.
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 ¶
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 ¶
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 int
// Description is a human-readable summary of what this migration does
// (e.g., "initial", "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 ¶
GetMigrations returns all migrations for the specified database dialect in version order.
Migration versioning:
- Version 001+: All migrations from migrations/<dialect>/*.sql
Migration file naming convention:
<version>_<description>.<up|down>.sql
Examples:
001_initial.up.sql - Initial schema migration 001_initial.down.sql - Revert initial schema 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 ¶
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 ¶
GetExpiresAt returns the session expiration timestamp.
func (*Session) GetRefreshToken ¶
GetRefreshToken returns the optional refresh token.
func (*Session) SetCreatedAt ¶
SetCreatedAt sets the session creation timestamp.
func (*Session) SetExpiresAt ¶
SetExpiresAt sets the session expiration timestamp.
func (*Session) SetIPAddress ¶
SetIPAddress sets the client IP address that created this session.
func (*Session) SetRefreshToken ¶
SetRefreshToken sets the optional refresh token.
func (*Session) SetUserAgent ¶
SetUserAgent sets the client user agent that created this session.
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) SetCreatedAt ¶
SetCreatedAt sets the user creation timestamp.
func (*User) SetUpdatedAt ¶
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.