Documentation Index
Fetch the complete documentation index at: https://mintlify.com/platforma-dev/platforma/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The auth package provides a full-featured authentication domain with user registration, login/logout, password management, and session-based authentication middleware.
Domain
auth.Domain
The main domain aggregate that bundles all auth components.
type Domain struct {
Repository *Repository
Service *Service
HandleGroup *httpserver.HandlerGroup
Middleware httpserver.Middleware
}
Database repository for user persistence
Business logic service for authentication operations
Pre-configured HTTP handlers for auth endpoints
Authentication middleware for protecting routes
Constructor
func New(
db db,
authStorage authStorage,
sessionCookieName string,
usernameValidator func(string) error,
passwordValidator func(string) error,
cleanupEnqueuer cleanupEnqueuer,
) *Domain
Database interface (sqlx-compatible)
Session storage interface (typically session.Service)
Name of the HTTP cookie for session ID
Custom username validation function (optional, uses default if nil)
Custom password validation function (optional, uses default if nil)
Queue enqueuer for user cleanup jobs (optional)
Service
auth.Service
Core business logic for authentication and user management.
type Service struct {
repo repository
authStorage authStorage
sessionCookieName string
usernameValidator func(string) error
passwordValidator func(string) error
cleanupEnqueuer cleanupEnqueuer
}
Methods
Register
func (s *Service) CreateWithLoginAndPassword(ctx context.Context, username, password string) error
Creates a new user account with username and password. Validates inputs, generates salt, hashes password with bcrypt.
Username for the new account (validated by usernameValidator)
Password for the new account (validated by passwordValidator)
Returns ErrInvalidUsername, ErrInvalidPassword, or creation error
Default validation rules:
- Username: 5-20 characters
- Password: 8-100 characters
Login
func (s *Service) CreateSessionFromUsernameAndPassword(ctx context.Context, username, password string) (string, error)
Authenticates user credentials and creates a new session.
New session ID on success
Returns ErrWrongUserOrPassword if credentials invalid
Logout
func (s *Service) DeleteSession(ctx context.Context, sessionId string) error
Deletes a session from storage.
Get User
func (s *Service) Get(ctx context.Context, id string) (*User, error)
Retrieves a user by ID.
func (s *Service) GetFromSession(ctx context.Context, sessionId string) (*User, error)
Retrieves a user from a session ID.
Change Password
func (s *Service) ChangePassword(ctx context.Context, currentPassword, newPassword string) error
Changes the authenticated user’s password. User must be in context (requires middleware).
Current password for verification
New password (validated by passwordValidator)
Returns ErrCurrentPasswordIncorrect, ErrInvalidPassword, or update error
Delete User
func (s *Service) DeleteUser(ctx context.Context) error
Deletes the authenticated user and all their sessions. User must be in context (requires middleware). Optionally enqueues cleanup job.
Repository
auth.Repository
Database operations for user persistence.
type Repository struct {
db db
}
Methods
func (r *Repository) Get(ctx context.Context, id string) (*User, error)
func (r *Repository) GetByUsername(ctx context.Context, username string) (*User, error)
func (r *Repository) Create(ctx context.Context, user *User) error
func (r *Repository) UpdatePassword(ctx context.Context, id, password, salt string) error
func (r *Repository) Delete(ctx context.Context, id string) error
func (r *Repository) Migrations() fs.FS
Middleware
auth.AuthenticationMiddleware
HTTP middleware that validates sessions and injects users into request context.
type AuthenticationMiddleware struct {
userService userService
}
func (m *AuthenticationMiddleware) Wrap(next http.Handler) http.Handler
Behavior:
- Reads session cookie from request
- Validates session with auth storage
- Retrieves user from session
- Injects user into request context
- Returns 401 Unauthorized if session invalid
Usage:
// Protect entire handler group
protectedAPI := httpserver.NewHandlerGroup()
protectedAPI.Use(authDomain.Middleware)
// Protect single handler
protectedHandler := authDomain.Middleware.Wrap(myHandler)
HTTP Handlers
All handlers are pre-configured in Domain.HandleGroup with these routes:
| Method | Route | Handler | Protected | Description |
|---|
| POST | /register | RegisterHandler | No | Create new user account |
| POST | /login | LoginHandler | No | Authenticate and create session |
| POST | /logout | LogoutHandler | No | Delete session and clear cookie |
| GET | /me | GetHandler | No | Get current user info |
| POST | /change-password | ChangePasswordHandler | Yes | Change user password |
| DELETE | /me | DeleteHandler | Yes | Delete user account |
POST /register
Request:
{
"login": "username",
"password": "password123"
}
Response:
201 Created - User created successfully
400 Bad Request - Invalid username or password
500 Internal Server Error - Creation failed
POST /login
Request:
{
"login": "username",
"password": "password123"
}
Response:
200 OK - Sets session cookie
401 Unauthorized - Invalid credentials
500 Internal Server Error - Session creation failed
POST /logout
Response:
200 OK - Clears session cookie
500 Internal Server Error - Session deletion failed
GET /me
Response:
{
"username": "username"
}
200 OK - Returns user info
401 Unauthorized - No valid session
500 Internal Server Error - Retrieval failed
POST /change-password
Request:
{
"currentPassword": "oldpass123",
"newPassword": "newpass456"
}
Response:
200 OK - Password changed
400 Bad Request - Invalid new password
401 Unauthorized - Current password incorrect
500 Internal Server Error - Update failed
DELETE /me
Response:
200 OK - User deleted
401 Unauthorized - No valid session
500 Internal Server Error - Deletion failed
Models
User
type User struct {
ID string `db:"id" json:"id"`
Username string `db:"username" json:"username"`
Password string `db:"password" json:"password"`
Salt string `db:"salt" json:"salt"`
Created time.Time `db:"created" json:"created"`
Updated time.Time `db:"updated" json:"updated"`
Status Status `db:"status" json:"status"`
}
Bcrypt-hashed password with salt
Random UUID used in password hashing
Account creation timestamp
Account status: “active”, “inactive”, or “deleted”
Status
type Status string
const (
StatusActive Status = "active"
StatusInactive Status = "inactive"
StatusDeleted Status = "deleted"
)
Context Helpers
UserFromContext
func UserFromContext(ctx context.Context) *User
Retrieves the authenticated user from request context. Returns nil if no user in context.
Usage:
user := auth.UserFromContext(r.Context())
if user == nil {
// Not authenticated
}
Errors
var (
ErrUserNotFound = errors.New("user not found")
ErrWrongUserOrPassword = errors.New("wrong user or password")
ErrInvalidUsername = errors.New("invalid username")
ErrShortUsername = errors.New("short username")
ErrLongUsername = errors.New("long username")
ErrInvalidPassword = errors.New("invalid password")
ErrShortPassword = errors.New("short password")
ErrLongPassword = errors.New("long password")
ErrCurrentPasswordIncorrect = errors.New("current password is incorrect")
)
Complete Example
package main
import (
"github.com/platforma-dev/platforma/application"
"github.com/platforma-dev/platforma/auth"
"github.com/platforma-dev/platforma/database"
"github.com/platforma-dev/platforma/httpserver"
"github.com/platforma-dev/platforma/session"
)
func main() {
app := application.New()
// Setup database
dbDomain := database.New(database.Config{
Host: "localhost",
Port: 5432,
Database: "myapp",
User: "postgres",
Password: "password",
})
app.AddDomain("database", dbDomain)
// Setup session storage
sessionDomain := session.New(dbDomain.Service)
app.AddDomain("session", sessionDomain)
// Setup auth with custom validators
authDomain := auth.New(
dbDomain.Service,
sessionDomain.Service,
"session_id",
func(username string) error {
if len(username) < 3 {
return errors.New("username too short")
}
return nil
},
func(password string) error {
if len(password) < 12 {
return errors.New("password must be 12+ chars")
}
return nil
},
nil, // no cleanup enqueuer
)
app.AddDomain("auth", authDomain)
// Setup HTTP server
server := httpserver.New(":8080")
// Mount auth endpoints at /auth
server.Handle("/auth/", http.StripPrefix("/auth", authDomain.HandleGroup))
// Protect application routes
protectedAPI := httpserver.NewHandlerGroup()
protectedAPI.Use(authDomain.Middleware)
protectedAPI.Handle("GET /profile", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user := auth.UserFromContext(r.Context())
json.NewEncoder(w).Encode(map[string]string{
"user_id": user.ID,
"username": user.Username,
})
}))
server.Handle("/api/", http.StripPrefix("/api", protectedAPI))
app.AddRunner("httpserver", server)
if err := app.Run(); err != nil {
panic(err)
}
}
Authentication Flow
- Registration: User submits username/password → Service validates → Repository creates user with hashed password
- Login: User submits credentials → Service verifies password → Session created → Cookie set
- Protected Request: Request with cookie → Middleware validates session → User injected into context → Handler executes
- Logout: Logout request → Service deletes session → Cookie cleared
- Password Change: Authenticated user submits old/new password → Service verifies old password → Updates with new hashed password
- Account Deletion: Authenticated user requests deletion → Service deletes all sessions → Deletes user → Enqueues cleanup job