Help us shape the future of Go! Take the 2026 Go Developer Survey

user

package
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package user defines the user domain entity and its store interface.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NormalizeEmail

func NormalizeEmail(email string) string

NormalizeEmail lowercases and trims an email address so lookups and uniqueness checks are case-insensitive and whitespace-insensitive.

Types

type List

type List struct {
	Users      []*User `json:"users"`
	NextCursor string  `json:"next_cursor,omitempty"`
	Total      int     `json:"total"`
}

List is a paginated list of users.

type Metadata

type Metadata map[string]string

Metadata holds arbitrary user metadata as typed key-value pairs.

type Query

type Query struct {
	AppID  id.AppID         `json:"app_id"`
	EnvID  id.EnvironmentID `json:"env_id,omitempty"`
	Email  string           `json:"email,omitempty"`
	Cursor string           `json:"cursor,omitempty"`
	Limit  int              `json:"limit,omitempty"`
}

Query holds query parameters for listing users.

type Store

type Store interface {
	CreateUser(ctx context.Context, u *User) error
	GetUser(ctx context.Context, userID id.UserID) (*User, error)
	// GetUserByEmail resolves the user whose primary email matches within
	// (appID, envID). A nil envID matches app-wide, mirroring GetUserByAnyEmail.
	GetUserByEmail(ctx context.Context, appID id.AppID, envID id.EnvironmentID, email string) (*User, error)
	// GetUserByPhone resolves the user owning phone within (appID, envID).
	// A nil envID matches app-wide, mirroring GetUserByAnyEmail.
	GetUserByPhone(ctx context.Context, appID id.AppID, envID id.EnvironmentID, phone string) (*User, error)
	// GetUserByUsername resolves the user owning username within (appID,
	// envID). A nil envID matches app-wide, which is what the signup and
	// rename guards rely on to keep handles unique across a whole app.
	GetUserByUsername(ctx context.Context, appID id.AppID, envID id.EnvironmentID, username string) (*User, error)
	UpdateUser(ctx context.Context, u *User) error
	DeleteUser(ctx context.Context, userID id.UserID) error
	ListUsers(ctx context.Context, q *Query) (*List, error)

	// CreateUserWithPrimaryEmail creates a user and its primary email row.
	// The address must be free within (AppID, EnvID), else ErrEmailTaken.
	CreateUserWithPrimaryEmail(ctx context.Context, u *User, primary *UserEmail) error

	// AddUserEmail attaches an additional email to a user. Returns
	// account.ErrEmailTaken if the address is already owned within the env.
	AddUserEmail(ctx context.Context, e *UserEmail) error

	// GetUserByAnyEmail resolves the user owning any (primary or secondary)
	// verified-or-not email matching (appID, envID, email). ErrNotFound when none.
	GetUserByAnyEmail(ctx context.Context, appID id.AppID, envID id.EnvironmentID, email string) (*User, error)

	// GetUserEmailRecord returns the email row matching (appID, envID, email)
	// so callers can inspect Verified before linking. ErrNotFound when none.
	GetUserEmailRecord(ctx context.Context, appID id.AppID, envID id.EnvironmentID, email string) (*UserEmail, error)

	// GetUserEmails returns all live emails for a user, primary first.
	GetUserEmails(ctx context.Context, userID id.UserID) ([]*UserEmail, error)

	// MarkUserEmailVerified marks an email verified, mirroring onto the user
	// record when it is the primary email.
	MarkUserEmailVerified(ctx context.Context, userID id.UserID, email string) error

	// SetPrimaryEmail makes a verified, user-owned email primary, updating the
	// user mirror. Returns account.ErrEmailNotVerified if the target is unverified.
	SetPrimaryEmail(ctx context.Context, userID id.UserID, email string) error

	// DeleteUserEmail soft-deletes a non-primary email. Refuses the primary
	// with store.ErrConflict.
	DeleteUserEmail(ctx context.Context, userID id.UserID, email string) error
}

Store defines the persistence interface for user operations.

type User

type User struct {
	ID                id.UserID        `json:"id"`
	AppID             id.AppID         `json:"app_id"`
	EnvID             id.EnvironmentID `json:"env_id"`
	Email             string           `json:"email"`
	EmailVerified     bool             `json:"email_verified"`
	FirstName         string           `json:"first_name"`
	LastName          string           `json:"last_name"`
	Image             string           `json:"image,omitempty"`
	Username          string           `json:"username,omitempty"`
	DisplayUsername   string           `json:"display_username,omitempty"`
	Phone             string           `json:"phone,omitempty"`
	PhoneVerified     bool             `json:"phone_verified"`
	PasswordHash      string           `json:"-"`
	PasswordChangedAt *time.Time       `json:"password_changed_at,omitempty"`
	Banned            bool             `json:"banned"`
	BanReason         string           `json:"ban_reason,omitempty"`
	BanExpires        *time.Time       `json:"ban_expires,omitempty"`
	Metadata          Metadata         `json:"metadata,omitempty"`
	CreatedAt         time.Time        `json:"created_at"`
	UpdatedAt         time.Time        `json:"updated_at"`
	DeletedAt         *time.Time       `json:"deleted_at,omitempty"`
}

User represents an authenticated identity within an application.

func (*User) IsBanned

func (u *User) IsBanned(now time.Time) bool

IsBanned reports whether the user is barred from authenticating at the given instant. A ban with an expiry in the past no longer applies.

func (*User) Name

func (u *User) Name() string

Name returns the full name by joining FirstName and LastName.

type UserEmail

type UserEmail struct {
	ID        id.UserEmailID   `json:"id"`
	UserID    id.UserID        `json:"user_id"`
	AppID     id.AppID         `json:"app_id"`
	EnvID     id.EnvironmentID `json:"env_id"`
	Email     string           `json:"email"` // always stored lowercased + trimmed
	Verified  bool             `json:"verified"`
	IsPrimary bool             `json:"is_primary"`
	Source    string           `json:"source"` // e.g. "password", "social:github", "sso", "scim", "admin", "backfill"
	CreatedAt time.Time        `json:"created_at"`
	UpdatedAt time.Time        `json:"updated_at"`
	DeletedAt *time.Time       `json:"deleted_at,omitempty"`
}

UserEmail is a single email address belonging to a user. A user may own multiple emails; exactly one is marked primary and mirrors User.Email / User.EmailVerified. Email uniqueness is enforced per (AppID, EnvID, Email) so an address can belong to at most one account within an environment.

func NewPrimaryEmail

func NewPrimaryEmail(u *User, source string) *UserEmail

NewPrimaryEmail builds the primary UserEmail row mirroring a user's current Email/EmailVerified, for use with Store.CreateUserWithPrimaryEmail. source records where the address came from (e.g. "password", "sso", "scim").

Jump to

Keyboard shortcuts

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