auth

package
v0.0.0-...-9c7a04a Latest Latest
Warning

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

Go to latest
Published: Mar 8, 2026 License: EUPL-1.2 Imports: 34 Imported by: 0

Documentation

Overview

Package auth provides authentication as a burrow contrib app.

It implements WebAuthn (passkeys), recovery codes, email verification, and invite-only registration. Context helpers provide access to the authenticated user from any handler.

Index

Constants

View Source
const (
	RoleUser  = "user"
	RoleAdmin = "admin"
)

Role constants.

View Source
const (
	// TokenLength is the number of random bytes for verification tokens.
	TokenLength = 32
	// TokenExpiry is how long verification tokens are valid.
	TokenExpiry = 24 * time.Hour
	// InviteExpiry is how long an invite token is valid.
	InviteExpiry = 7 * 24 * time.Hour
)
View Source
const (
	// CodeLength is the length of each recovery code (without dashes).
	CodeLength = 12
	// CodeCount is the default number of recovery codes to generate.
	CodeCount = 8
)

Variables

View Source
var ErrNotFound = sql.ErrNoRows

ErrNotFound is returned when a record is not found.

Functions

func DefaultAuthLayout

func DefaultAuthLayout() burrow.LayoutFunc

DefaultAuthLayout returns a minimal HTML layout for unauthenticated auth pages. It renders a clean page with Bootstrap CSS but no navbar or navigation. This is used as the default for auth.New(); pass a custom layout via WithAuthLayout() to override.

func GenerateInviteToken

func GenerateInviteToken() (plaintext, hash string, err error)

GenerateInviteToken generates a random invite token and its SHA256 hash.

func GenerateToken

func GenerateToken() (string, string, time.Time, error)

GenerateToken generates a new verification token. Returns (plaintext token, SHA256 hash for storage, expiry time, error).

func HashToken

func HashToken(token string) string

HashToken computes the SHA256 hash of a token.

func IsAdminEditLastAdmin

func IsAdminEditLastAdmin(ctx context.Context) bool

IsAdminEditLastAdmin reports whether the viewed user is the only remaining admin.

func IsAdminEditSelf

func IsAdminEditSelf(ctx context.Context) bool

IsAdminEditSelf reports whether the admin is viewing their own user detail page.

func IsAuthenticated

func IsAuthenticated(ctx context.Context) bool

IsAuthenticated returns true if a user is present in the context.

func LogoFromContext

func LogoFromContext(ctx context.Context) template.HTML

LogoFromContext retrieves the logo HTML from context, or empty if not set.

func NormalizeCode

func NormalizeCode(code string) string

NormalizeCode removes dashes and converts to lowercase for comparison.

func RequireAdmin

func RequireAdmin() func(http.Handler) http.Handler

RequireAdmin returns middleware that returns 403 if the user is not an admin.

func RequireAuth

func RequireAuth() func(http.Handler) http.Handler

RequireAuth returns middleware that redirects to login if not authenticated. The original request URL is stored in the session as "redirect_after_login" so the user can be redirected back after successful authentication.

func SafeRedirectPath

func SafeRedirectPath(next, defaultPath string) string

SafeRedirectPath validates a redirect path, falling back to defaultPath.

func TransportsFromWebAuthn

func TransportsFromWebAuthn(transports []protocol.AuthenticatorTransport) string

TransportsFromWebAuthn converts WebAuthn transports to a comma-separated string.

func WithLogo(ctx context.Context, logo template.HTML) context.Context

WithLogo returns a new context with the logo HTML set.

func WithUser

func WithUser(ctx context.Context, user *User) context.Context

WithUser returns a new context with the user set.

Types

type App

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

App implements the auth contrib app.

func New

func New(opts ...Option) *App

New creates a new auth app with the given options. By default, the built-in HTML renderer and auth layout are used. Use WithRenderer() and WithAuthLayout() to override.

func (*App) AdminNavItems

func (a *App) AdminNavItems() []burrow.NavItem

AdminNavItems returns navigation items for the admin panel.

func (*App) AdminRoutes

func (a *App) AdminRoutes(r chi.Router)

AdminRoutes registers admin routes for user and invite management. The router is expected to already have auth middleware applied.

func (*App) CLICommands

func (a *App) CLICommands() []*cli.Command

CLICommands returns auth-related CLI subcommands (promote, demote, create-invite).

func (*App) Configure

func (a *App) Configure(cmd *cli.Command) error

func (*App) Dependencies

func (a *App) Dependencies() []string

func (*App) Flags

func (a *App) Flags(configSource func(key string) cli.ValueSource) []cli.Flag

func (*App) FuncMap

func (a *App) FuncMap() template.FuncMap

FuncMap returns static template functions for auth templates.

func (*App) Handlers

func (a *App) Handlers() *Handlers

Handlers returns the auth handlers for external access.

func (*App) Middleware

func (a *App) Middleware() []func(http.Handler) http.Handler

func (*App) MigrationFS

func (a *App) MigrationFS() fs.FS

func (*App) Name

func (a *App) Name() string

func (*App) Register

func (a *App) Register(cfg *burrow.AppConfig) error

func (*App) Repo

func (a *App) Repo() *Repository

Repo returns the auth repository for external access.

func (*App) RequestFuncMap

func (a *App) RequestFuncMap(r *http.Request) template.FuncMap

RequestFuncMap returns request-scoped template functions for auth state.

func (*App) Routes

func (a *App) Routes(r chi.Router)

Routes registers auth HTTP routes.

func (*App) Shutdown

func (a *App) Shutdown(_ context.Context) error

Shutdown stops the background cleanup goroutine. Safe to call multiple times or if Configure was never called.

func (*App) StaticFS

func (a *App) StaticFS() (string, fs.FS)

StaticFS returns the embedded static assets (webauthn.js) under the "auth" prefix.

func (*App) TemplateFS

func (a *App) TemplateFS() fs.FS

TemplateFS returns the embedded HTML template files.

func (*App) TranslationFS

func (a *App) TranslationFS() fs.FS

TranslationFS returns the embedded translation files for auto-discovery by the i18n app.

type Config

type Config struct {
	LoginRedirect       string
	LogoutRedirect      string
	BaseURL             string
	UseEmail            bool
	RequireVerification bool
	InviteOnly          bool
}

Config holds auth-specific configuration.

type CreateInviteRequest

type CreateInviteRequest struct {
	Label string `form:"label"`
	Email string `form:"email"`
}

CreateInviteRequest is the request body for creating an invite.

type Credential

type Credential struct {
	bun.BaseModel   `bun:"table:credentials,alias:c"`
	DeletedAt       time.Time `bun:",soft_delete,nullzero" json:"-"`
	CreatedAt       time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"created_at"`
	AttestationType string    `json:"-"`
	Transports      string    `json:"-"`
	Name            string    `bun:",notnull" json:"name"`
	CredentialID    []byte    `bun:",unique,notnull" json:"-"`
	PublicKey       []byte    `bun:",notnull" json:"-"`
	AAGUID          []byte    `json:"-"`
	ID              int64     `bun:",pk,autoincrement" json:"id"`
	UserID          int64     `bun:",notnull" json:"user_id"`
	SignCount       uint32    `bun:",default:0" json:"-"`
	BackupState     bool      `bun:",default:false" json:"-"`
	BackupEligible  bool      `bun:",default:false" json:"-"`
}

Credential stores a WebAuthn credential for a user.

func NewCredentialFromWebAuthn

func NewCredentialFromWebAuthn(userID int64, cred *webauthn.Credential) *Credential

NewCredentialFromWebAuthn creates a Credential from a WebAuthn registration result.

func (*Credential) ToWebAuthn

func (c *Credential) ToWebAuthn() webauthn.Credential

ToWebAuthn converts the stored credential to the WebAuthn library type.

type EmailService

type EmailService interface {
	SendVerification(ctx context.Context, toEmail, verifyURL string) error
	SendInvite(ctx context.Context, toEmail, inviteURL string) error
}

EmailService defines email operations.

type EmailVerificationToken

type EmailVerificationToken struct {
	bun.BaseModel `bun:"table:email_verification_tokens,alias:evt"`
	ExpiresAt     time.Time `bun:",notnull" json:"expires_at"`
	CreatedAt     time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"created_at"`
	DeletedAt     time.Time `bun:",soft_delete,nullzero" json:"-"`
	TokenHash     string    `bun:",unique,notnull" json:"-"`
	ID            int64     `bun:",pk,autoincrement" json:"id"`
	UserID        int64     `bun:",notnull" json:"user_id"`
}

EmailVerificationToken stores a hashed token for email verification.

type Handlers

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

Handlers contains all auth and invite HTTP handlers.

func NewHandlers

func NewHandlers(
	repo *Repository,
	wa WebAuthnService,
	email EmailService,
	renderer Renderer,
	config *Config,
) *Handlers

NewHandlers creates a new Handlers instance. email can be nil if email mode is disabled.

func (*Handlers) AcknowledgeRecoveryCodes

func (h *Handlers) AcknowledgeRecoveryCodes(w http.ResponseWriter, r *http.Request) error

AcknowledgeRecoveryCodes clears recovery codes from the session and redirects.

func (*Handlers) AddCredentialBegin

func (h *Handlers) AddCredentialBegin(w http.ResponseWriter, r *http.Request) error

AddCredentialBegin starts the process of adding a new credential.

func (*Handlers) AddCredentialFinish

func (h *Handlers) AddCredentialFinish(w http.ResponseWriter, r *http.Request) error

AddCredentialFinish completes adding a new credential.

func (*Handlers) CredentialsPage

func (h *Handlers) CredentialsPage(w http.ResponseWriter, r *http.Request) error

CredentialsPage renders the credentials management page.

func (*Handlers) DeleteCredential

func (h *Handlers) DeleteCredential(w http.ResponseWriter, r *http.Request) error

DeleteCredential removes a credential.

func (*Handlers) IsInviteOnly

func (h *Handlers) IsInviteOnly() bool

IsInviteOnly returns true if invite-only registration is enabled.

func (*Handlers) LoginBegin

func (h *Handlers) LoginBegin(w http.ResponseWriter, r *http.Request) error

LoginBegin starts the WebAuthn discoverable login process.

func (*Handlers) LoginFinish

func (h *Handlers) LoginFinish(w http.ResponseWriter, r *http.Request) error

LoginFinish completes the WebAuthn discoverable login.

func (*Handlers) LoginPage

func (h *Handlers) LoginPage(w http.ResponseWriter, r *http.Request) error

LoginPage renders the login page.

func (*Handlers) Logout

func (h *Handlers) Logout(w http.ResponseWriter, r *http.Request) error

Logout clears the session cookie.

func (*Handlers) RecoveryCodesPage

func (h *Handlers) RecoveryCodesPage(w http.ResponseWriter, r *http.Request) error

RecoveryCodesPage renders the dedicated recovery codes page. Codes are read from the session; if none are present, redirects to login redirect.

func (*Handlers) RecoveryLogin

func (h *Handlers) RecoveryLogin(w http.ResponseWriter, r *http.Request) error

RecoveryLogin authenticates a user with a recovery code.

func (*Handlers) RecoveryPage

func (h *Handlers) RecoveryPage(w http.ResponseWriter, r *http.Request) error

RecoveryPage renders the recovery login page.

func (*Handlers) RegenerateRecoveryCodes

func (h *Handlers) RegenerateRecoveryCodes(w http.ResponseWriter, r *http.Request) error

RegenerateRecoveryCodes generates new recovery codes and invalidates old ones. Stores codes in session and returns a redirect to the recovery codes page.

func (*Handlers) RegisterBegin

func (h *Handlers) RegisterBegin(w http.ResponseWriter, r *http.Request) error

RegisterBegin starts the WebAuthn registration process.

func (*Handlers) RegisterFinish

func (h *Handlers) RegisterFinish(w http.ResponseWriter, r *http.Request) error

RegisterFinish completes the WebAuthn registration process.

func (*Handlers) RegisterPage

func (h *Handlers) RegisterPage(w http.ResponseWriter, r *http.Request) error

RegisterPage renders the registration page.

func (*Handlers) ResendVerification

func (h *Handlers) ResendVerification(w http.ResponseWriter, r *http.Request) error

ResendVerification resends the verification email.

func (*Handlers) UseEmailMode

func (h *Handlers) UseEmailMode() bool

UseEmailMode returns true if email-based authentication is enabled.

func (*Handlers) VerifyEmail

func (h *Handlers) VerifyEmail(w http.ResponseWriter, r *http.Request) error

VerifyEmail handles the email verification link.

func (*Handlers) VerifyPendingPage

func (h *Handlers) VerifyPendingPage(w http.ResponseWriter, r *http.Request) error

VerifyPendingPage renders the "check your email" page.

type Invite

type Invite struct {
	bun.BaseModel `bun:"table:invites,alias:inv"`
	ExpiresAt     time.Time  `bun:",notnull" json:"expires_at" form:"-" verbose:"Expires at"`
	CreatedAt     time.Time  `bun:",nullzero,notnull,default:current_timestamp" json:"created_at" form:"-" verbose:"Created at"`
	DeletedAt     time.Time  `bun:",soft_delete,nullzero" json:"-" form:"-"`
	UsedAt        *time.Time `json:"used_at,omitempty" form:"-"`
	UsedBy        *int64     `json:"used_by,omitempty" form:"-"`
	CreatedBy     *int64     `json:"created_by,omitempty" form:"-"`
	Email         string     `bun:",notnull" json:"email" verbose:"Email"`
	Label         string     `bun:",notnull,default:''" json:"label" verbose:"Label"`
	TokenHash     string     `bun:",unique,notnull" json:"-" form:"-"`
	ID            int64      `bun:",pk,autoincrement" json:"id" verbose:"ID"`
}

Invite represents an invitation to register.

func (*Invite) IsExpired

func (i *Invite) IsExpired() bool

IsExpired returns true if the invite has expired.

func (*Invite) IsUsed

func (i *Invite) IsUsed() bool

IsUsed returns true if the invite has been used.

func (*Invite) IsValid

func (i *Invite) IsValid() bool

IsValid returns true if the invite is neither used nor expired.

type Option

type Option func(*App)

Option configures the auth app.

func WithAuthLayout

func WithAuthLayout(fn burrow.LayoutFunc) Option

WithAuthLayout sets an optional layout for public (unauthenticated) auth pages. When set, pages like login, register, and recovery use this layout instead of the global app layout. Authenticated routes (credentials, recovery codes) continue to use the global layout.

func WithEmailService

func WithEmailService(e EmailService) Option

WithEmailService sets the email service for the auth app.

func WithLogoComponent

func WithLogoComponent(c template.HTML) Option

WithLogoComponent sets an optional logo HTML rendered above auth page content. When set, the logo appears on login, register, and recovery pages.

func WithRenderer

func WithRenderer(r Renderer) Option

WithRenderer sets the page renderer for auth views.

type RecoveryCode

type RecoveryCode struct {
	bun.BaseModel `bun:"table:recovery_codes,alias:rc"`
	CreatedAt     time.Time  `bun:",nullzero,notnull,default:current_timestamp" json:"created_at"`
	DeletedAt     time.Time  `bun:",soft_delete,nullzero" json:"-"`
	UsedAt        *time.Time `json:"used_at,omitempty"`
	CodeHash      string     `bun:",notnull" json:"-"`
	ID            int64      `bun:",pk,autoincrement" json:"id"`
	UserID        int64      `bun:",notnull" json:"user_id"`
	Used          bool       `bun:",notnull,default:false" json:"used"`
}

RecoveryCode stores a hashed recovery code for account recovery.

type RecoveryLoginRequest

type RecoveryLoginRequest struct {
	Username string `json:"username" form:"username"`
	Code     string `json:"code" form:"code"`
}

RecoveryLoginRequest is the request body for recovery login.

type RecoveryService

type RecoveryService struct{}

RecoveryService handles recovery code generation.

func NewRecoveryService

func NewRecoveryService() *RecoveryService

NewRecoveryService creates a new recovery service.

func (*RecoveryService) GenerateCodes

func (s *RecoveryService) GenerateCodes(count int) ([]string, []string, error)

GenerateCodes generates recovery codes and their bcrypt hashes. Returns (plaintext codes for display, hashed codes for storage, error).

type RegisterBeginRequest

type RegisterBeginRequest struct {
	Username string `json:"username"`
	Email    string `json:"email"`
	Name     string `json:"name"`
	Invite   string `json:"invite"`
}

RegisterBeginRequest is the request body for starting registration.

type Renderer

type Renderer interface {
	RegisterPage(w http.ResponseWriter, r *http.Request, useEmail, inviteOnly bool, email, invite string) error
	LoginPage(w http.ResponseWriter, r *http.Request, loginRedirect string) error
	CredentialsPage(w http.ResponseWriter, r *http.Request, creds []Credential) error
	RecoveryPage(w http.ResponseWriter, r *http.Request, loginRedirect string) error
	RecoveryCodesPage(w http.ResponseWriter, r *http.Request, codes []string) error
	VerifyPendingPage(w http.ResponseWriter, r *http.Request) error
	VerifyEmailSuccess(w http.ResponseWriter, r *http.Request) error
	VerifyEmailError(w http.ResponseWriter, r *http.Request, errorCode string) error
}

Renderer defines the page rendering interface for auth templates. Projects implement this to provide their own template rendering.

func DefaultRenderer

func DefaultRenderer() Renderer

DefaultRenderer returns the default Renderer that uses the built-in HTML templates. Templates use burrow.RenderTemplate which reads layout from context: if a layout is set, page content is wrapped in it; otherwise bare content is rendered.

type Repository

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

Repository provides data access for auth models.

func NewRepository

func NewRepository(db *bun.DB) *Repository

NewRepository creates a new auth Repository.

func (*Repository) CountAdminUsers

func (r *Repository) CountAdminUsers(ctx context.Context) (int, error)

CountAdminUsers returns the number of users with the admin role.

func (*Repository) CountUserCredentials

func (r *Repository) CountUserCredentials(ctx context.Context, userID int64) (int64, error)

CountUserCredentials counts the number of credentials for a user.

func (*Repository) CountUsers

func (r *Repository) CountUsers(ctx context.Context) (int, error)

CountUsers returns the total number of non-deleted users.

func (*Repository) CreateCredential

func (r *Repository) CreateCredential(ctx context.Context, cred *Credential) error

CreateCredential creates a new WebAuthn credential.

func (*Repository) CreateEmailVerificationToken

func (r *Repository) CreateEmailVerificationToken(ctx context.Context, userID int64, tokenHash string, expiresAt time.Time) error

CreateEmailVerificationToken creates a new email verification token.

func (*Repository) CreateInvite

func (r *Repository) CreateInvite(ctx context.Context, invite *Invite) error

CreateInvite creates a new invite record.

func (*Repository) CreateRecoveryCodes

func (r *Repository) CreateRecoveryCodes(ctx context.Context, userID int64, codeHashes []string) error

CreateRecoveryCodes creates recovery codes for a user.

func (*Repository) CreateUser

func (r *Repository) CreateUser(ctx context.Context, username, name string) (*User, error)

CreateUser creates a new user with a username and optional name.

func (*Repository) CreateUserWithEmail

func (r *Repository) CreateUserWithEmail(ctx context.Context, email, name string) (*User, error)

CreateUserWithEmail creates a new user with email and optional name.

func (*Repository) DeleteCredential

func (r *Repository) DeleteCredential(ctx context.Context, credID, userID int64) error

DeleteCredential soft-deletes a credential.

func (*Repository) DeleteEmailVerificationToken

func (r *Repository) DeleteEmailVerificationToken(ctx context.Context, tokenID int64) error

DeleteEmailVerificationToken hard-deletes a token.

func (*Repository) DeleteExpiredEmailVerificationTokens

func (r *Repository) DeleteExpiredEmailVerificationTokens(ctx context.Context) error

DeleteExpiredEmailVerificationTokens hard-deletes expired tokens.

func (*Repository) DeleteInvite

func (r *Repository) DeleteInvite(ctx context.Context, inviteID int64) error

DeleteInvite hard-deletes an invite (revoke).

func (*Repository) DeleteRecoveryCodes

func (r *Repository) DeleteRecoveryCodes(ctx context.Context, userID int64) error

DeleteRecoveryCodes hard-deletes all recovery codes for a user.

func (*Repository) DeleteUser

func (r *Repository) DeleteUser(ctx context.Context, id int64) error

DeleteUser soft-deletes a user by ID.

func (*Repository) DeleteUserEmailVerificationTokens

func (r *Repository) DeleteUserEmailVerificationTokens(ctx context.Context, userID int64) error

DeleteUserEmailVerificationTokens hard-deletes all tokens for a user.

func (*Repository) EmailExists

func (r *Repository) EmailExists(ctx context.Context, email string) (bool, error)

EmailExists checks if a user with the given email exists.

func (*Repository) GetCredentialsByUserID

func (r *Repository) GetCredentialsByUserID(ctx context.Context, userID int64) ([]Credential, error)

GetCredentialsByUserID retrieves all credentials for a user.

func (*Repository) GetEmailVerificationToken

func (r *Repository) GetEmailVerificationToken(ctx context.Context, tokenHash string) (*EmailVerificationToken, error)

GetEmailVerificationToken retrieves a token by hash.

func (*Repository) GetInviteByTokenHash

func (r *Repository) GetInviteByTokenHash(ctx context.Context, tokenHash string) (*Invite, error)

GetInviteByTokenHash retrieves an invite by its token hash.

func (*Repository) GetUnusedRecoveryCodeCount

func (r *Repository) GetUnusedRecoveryCodeCount(ctx context.Context, userID int64) (int64, error)

GetUnusedRecoveryCodeCount returns the count of unused recovery codes.

func (*Repository) GetUnusedRecoveryCodes

func (r *Repository) GetUnusedRecoveryCodes(ctx context.Context, userID int64) ([]RecoveryCode, error)

GetUnusedRecoveryCodes retrieves unused recovery codes for a user.

func (*Repository) GetUserByEmail

func (r *Repository) GetUserByEmail(ctx context.Context, email string) (*User, error)

GetUserByEmail retrieves a user by email.

func (*Repository) GetUserByID

func (r *Repository) GetUserByID(ctx context.Context, id int64) (*User, error)

GetUserByID retrieves a user by ID.

func (*Repository) GetUserByIDWithCredentials

func (r *Repository) GetUserByIDWithCredentials(ctx context.Context, id int64) (*User, error)

GetUserByIDWithCredentials retrieves a user by ID with preloaded credentials.

func (*Repository) GetUserByUsername

func (r *Repository) GetUserByUsername(ctx context.Context, username string) (*User, error)

GetUserByUsername retrieves a user by username.

func (*Repository) HasRecoveryCodes

func (r *Repository) HasRecoveryCodes(ctx context.Context, userID int64) (bool, error)

HasRecoveryCodes checks if a user has any recovery codes.

func (*Repository) ListInvites

func (r *Repository) ListInvites(ctx context.Context) ([]Invite, error)

ListInvites returns all invites ordered by creation date descending.

func (*Repository) ListUsers

func (r *Repository) ListUsers(ctx context.Context) ([]User, error)

ListUsers returns all non-deleted users ordered by ID ascending.

func (*Repository) MarkEmailVerified

func (r *Repository) MarkEmailVerified(ctx context.Context, userID int64) error

MarkEmailVerified marks a user's email as verified.

func (*Repository) MarkInviteUsed

func (r *Repository) MarkInviteUsed(ctx context.Context, inviteID, userID int64) error

MarkInviteUsed marks an invite as used by the given user.

func (*Repository) MarkRecoveryCodeUsed

func (r *Repository) MarkRecoveryCodeUsed(ctx context.Context, codeID int64) error

MarkRecoveryCodeUsed marks a recovery code as used.

func (*Repository) SetUserActive

func (r *Repository) SetUserActive(ctx context.Context, userID int64, active bool) error

SetUserActive sets a user's is_active flag.

func (*Repository) SetUserRole

func (r *Repository) SetUserRole(ctx context.Context, userID int64, role string) error

SetUserRole updates a user's role.

func (*Repository) UpdateCredentialSignCount

func (r *Repository) UpdateCredentialSignCount(ctx context.Context, credentialID []byte, signCount uint32) error

UpdateCredentialSignCount updates the sign count for a credential.

func (*Repository) UpdateUser

func (r *Repository) UpdateUser(ctx context.Context, user *User) error

UpdateUser updates a user record.

func (*Repository) UserExists

func (r *Repository) UserExists(ctx context.Context, username string) (bool, error)

UserExists checks if a user with the given username exists.

func (*Repository) ValidateAndUseRecoveryCode

func (r *Repository) ValidateAndUseRecoveryCode(ctx context.Context, userID int64, code string) (bool, error)

ValidateAndUseRecoveryCode validates and marks a recovery code as used.

type ResendVerificationRequest

type ResendVerificationRequest struct {
	Email string `json:"email" form:"email"`
}

ResendVerificationRequest is the request body for resending verification email.

type User

type User struct {
	bun.BaseModel   `bun:"table:users,alias:u"`
	DeletedAt       time.Time    `bun:",soft_delete,nullzero" json:"-" form:"-"`
	UpdatedAt       time.Time    `bun:",nullzero" json:"updated_at" form:"-"`
	CreatedAt       time.Time    `bun:",nullzero,notnull,default:current_timestamp" json:"created_at" form:"-" verbose:"Created at"`
	EmailVerifiedAt *time.Time   `json:"email_verified_at,omitempty" form:"-"`
	Email           *string      `bun:",unique" json:"email,omitempty" form:"-" verbose:"Email"`
	Name            string       `bun:",nullzero" json:"name,omitempty" verbose:"Name"`
	Bio             string       `bun:",nullzero" json:"bio,omitempty"`
	Role            string       `bun:",notnull,default:'user'" json:"role" verbose:"Role"`
	Username        string       `bun:",unique,notnull" json:"username" form:"-" verbose:"Username"`
	Credentials     []Credential `bun:"rel:has-many,join:id=user_id" json:"credentials,omitempty" form:"-"`
	ID              int64        `bun:",pk,autoincrement" json:"id" verbose:"ID"`
	EmailVerified   bool         `bun:",notnull,default:false" json:"email_verified" form:"-"`
	IsActive        bool         `bun:",notnull,default:true" json:"is_active" form:"-" verbose:"Active"`
}

User represents an authenticated user with WebAuthn credentials.

func UserFromContext

func UserFromContext(ctx context.Context) *User

UserFromContext retrieves the authenticated user from the context.

func (*User) IsAdmin

func (u *User) IsAdmin() bool

IsAdmin returns true if the user has the admin role.

func (*User) WebAuthnCredentials

func (u *User) WebAuthnCredentials() []webauthn.Credential

WebAuthnCredentials returns the user's WebAuthn credentials.

func (*User) WebAuthnDisplayName

func (u *User) WebAuthnDisplayName() string

WebAuthnDisplayName returns the display name or falls back to username.

func (*User) WebAuthnID

func (u *User) WebAuthnID() []byte

WebAuthnID returns the user ID as bytes for the WebAuthn protocol.

func (*User) WebAuthnIcon

func (u *User) WebAuthnIcon() string

WebAuthnIcon returns an empty string (deprecated by the spec).

func (*User) WebAuthnName

func (u *User) WebAuthnName() string

WebAuthnName returns the username.

type WebAuthnService

type WebAuthnService interface {
	WebAuthn() *gowebauthn.WebAuthn
	StoreRegistrationSession(userID int64, data *gowebauthn.SessionData)
	GetRegistrationSession(userID int64) (*gowebauthn.SessionData, error)
	StoreDiscoverableSession(sessionID string, data *gowebauthn.SessionData)
	GetDiscoverableSession(sessionID string) (*gowebauthn.SessionData, error)
}

WebAuthnService defines WebAuthn operations.

func NewWebAuthnService

func NewWebAuthnService(ctx context.Context, rpDisplayName, rpID, rpOrigin string) (WebAuthnService, error)

NewWebAuthnService creates a new WebAuthn service with the given RP configuration. The context controls the lifetime of the background cleanup goroutine.

Jump to

Keyboard shortcuts

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