Documentation
¶
Overview ¶
Package auth is chatz's authentication domain: password hashing (bcrypt), server-side opaque session tokens (only the SHA-256 hash is stored; the raw token lives in the client's HttpOnly cookie), first-run admin bootstrap, and optional single-user passwordless auto-login. Handlers call this layer; it owns the users + sessions tables.
Index ¶
- Constants
- Variables
- func UserToAPI(u *models.User) api.User
- type Service
- func (s *Service) Authenticate(ctx context.Context, token string) (*models.User, error)
- func (s *Service) Bootstrap(ctx context.Context, username, password string) (*models.User, error)
- func (s *Service) CreateUser(ctx context.Context, username, password string, isAdmin bool) (*models.User, error)
- func (s *Service) DeleteUser(ctx context.Context, id uuid.UUID) error
- func (s *Service) ListUsers(ctx context.Context) ([]*models.User, error)
- func (s *Service) Login(ctx context.Context, username, password string) (string, *models.User, error)
- func (s *Service) Logout(ctx context.Context, token string) error
- func (s *Service) NeedsSetup(ctx context.Context) (bool, error)
- func (s *Service) PasswordlessLogin(ctx context.Context) (string, *models.User, error)
Constants ¶
const (
// CookieName is the session cookie holding the raw opaque token.
CookieName = "chatz_session"
)
Variables ¶
var ( // ErrInvalidCredentials is returned for an unknown user or a bad password. // Deliberately indistinguishable between the two (no user enumeration). ErrInvalidCredentials = errors.New("auth: invalid credentials") // ErrInvalidInput is returned for an empty username or password where one // is required. ErrInvalidInput = errors.New("auth: invalid input") // ErrUserExists is returned when the username is already taken. ErrUserExists = errors.New("auth: username already exists") // ErrSetupClosed is returned by Bootstrap once at least one user exists. ErrSetupClosed = errors.New("auth: setup already completed") // ErrSessionInvalid is returned for a missing, revoked, or expired session. ErrSessionInvalid = errors.New("auth: session invalid or expired") // disabled or the install is not a single-user one. ErrPasswordlessUnavailable = errors.New("auth: passwordless not available") )
Auth domain errors. The HTTP layer maps these to status codes (invalid credentials + invalid session -> 401, user-exists + setup-closed -> 409, invalid input -> 400). Declared with errors.New so they stay comparable across ctxerrors.Wrap layers via errors.Is.
Functions ¶
Types ¶
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is the auth domain service. Construct with New and share it — it is stateless beyond its query handle and config.
func New ¶
func New(q *repositories.Query, passwordless bool) *Service
New builds the Service over the given query handle. passwordless enables single-user auto-login (see PasswordlessLogin).
func (*Service) Authenticate ¶
Authenticate resolves a raw session token to its user, or ErrSessionInvalid if the session is missing, expired, or its user is gone.
func (*Service) Bootstrap ¶
func (s *Service) Bootstrap( ctx context.Context, username, password string, ) (*models.User, error)
Bootstrap creates the first user as admin. It fails with ErrSetupClosed once any user exists, and ErrInvalidInput without a password (the admin must have one — passwordless is opt-in per-config, not for the bootstrap account).
func (*Service) CreateUser ¶
func (s *Service) CreateUser( ctx context.Context, username, password string, isAdmin bool, ) (*models.User, error)
CreateUser provisions a user. An empty password creates a passwordless account (login only via PasswordlessLogin). Returns ErrUserExists if the username is taken, ErrInvalidInput if it's empty.
func (*Service) DeleteUser ¶
DeleteUser removes the user with id; the DB cascades their sessions + chats. Returns commerr.ErrNotFound when no user has that id.
func (*Service) Login ¶
func (s *Service) Login( ctx context.Context, username, password string, ) (string, *models.User, error)
Login verifies the password and issues a session, returning the raw token to set as a cookie. Unknown user and bad password both return ErrInvalidCredentials (no user enumeration).
func (*Service) Logout ¶
Logout revokes the session for the given raw token. A missing session is not an error — logout is idempotent.
func (*Service) NeedsSetup ¶
NeedsSetup reports whether the install has no users yet (first-run).
func (*Service) PasswordlessLogin ¶
PasswordlessLogin issues a session without a password, but ONLY when passwordless is enabled AND the install has exactly one user. Otherwise ErrPasswordlessUnavailable — it must never silently pick an account on a multi-user install.