pwdless

package
v0.0.0-...-741f16f Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2024 License: MIT Imports: 20 Imported by: 4

Documentation

Overview

Package pwdless provides JSON Web Token (JWT) authentication and authorization middleware. It implements a passwordless authentication flow by sending login tokens vie email which are then exchanged for JWT access and refresh tokens.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidLogin  = errors.New("invalid email address")
	ErrUnknownLogin  = errors.New("email not registered")
	ErrLoginDisabled = errors.New("login for account disabled")
	ErrLoginToken    = errors.New("invalid or expired login token")
)

The list of error types presented to the end user as error message.

View Source
var (
	ErrInternalServerError = &ErrResponse{
		HTTPStatusCode: http.StatusInternalServerError,
		StatusText:     http.StatusText(http.StatusInternalServerError),
	}
)

The list of default error types without specific error message.

Functions

func ErrUnauthorized

func ErrUnauthorized(err error) render.Renderer

ErrUnauthorized renders status 401 Unauthorized with custom error message.

Types

type Account

type Account struct {
	ID        int       `bun:"id,pk,autoincrement" json:"id"`
	CreatedAt time.Time `bun:"created_at,nullzero,notnull,default:current_timestamp" json:"created_at,omitempty"`
	UpdatedAt time.Time `bun:"updated_at,nullzero,notnull,default:current_timestamp" json:"updated_at,omitempty"`
	LastLogin time.Time `bun:"last_login" json:"last_login,omitempty"`

	Email  string   `bun:"email,notnull" json:"email"`
	Name   string   `bun:"name,notnull" json:"name"`
	Active bool     `bun:"active,notnull" json:"active"`
	Roles  []string `bun:"roles,array" json:"roles,omitempty"`

	Token []jwt.Token `bun:"rel:has-many" json:"token,omitempty"`
}

Account represents an authenticated application user

func (*Account) BeforeDelete

func (a *Account) BeforeDelete(db *bun.DB) error

BeforeDelete hook executed before database delete operation.

func (*Account) BeforeInsert

func (a *Account) BeforeInsert(db *bun.DB) error

BeforeInsert hook executed before database insert operation.

func (*Account) BeforeUpdate

func (a *Account) BeforeUpdate(db *bun.DB) error

BeforeUpdate hook executed before database update operation.

func (*Account) CanLogin

func (a *Account) CanLogin() bool

CanLogin returns true if user is allowed to login.

func (*Account) Claims

func (a *Account) Claims() jwt.AppClaims

Claims returns the account's claims to be signed

func (*Account) Validate

func (a *Account) Validate() error

Validate validates Account struct and returns validation errors.

type AuthStorer

type AuthStorer interface {
	GetAccount(id int) (*Account, error)
	GetAccountByEmail(email string) (*Account, error)
	UpdateAccount(a *Account) error

	GetToken(token string) (*jwt.Token, error)
	CreateOrUpdateToken(t *jwt.Token) error
	DeleteToken(t *jwt.Token) error
	PurgeExpiredToken() error
}

AuthStorer defines database operations on accounts and tokens.

type ErrResponse

type ErrResponse struct {
	Err            error `json:"-"` // low-level runtime error
	HTTPStatusCode int   `json:"-"` // http response status code

	StatusText string `json:"status"`          // user-level status message
	AppCode    int64  `json:"code,omitempty"`  // application-specific error code
	ErrorText  string `json:"error,omitempty"` // application-level error message, for debugging
}

ErrResponse renderer type for handling all sorts of errors.

func (*ErrResponse) Render

func (e *ErrResponse) Render(w http.ResponseWriter, r *http.Request) error

Render sets the application-specific error code in AppCode.

type LoginToken

type LoginToken struct {
	Token     string
	AccountID int
	Expiry    time.Time
}

LoginToken is an in-memory saved token referencing an account ID and an expiry date.

type LoginTokenAuth

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

LoginTokenAuth implements passwordless login authentication flow using temporary in-memory stored tokens.

func NewLoginTokenAuth

func NewLoginTokenAuth() (*LoginTokenAuth, error)

NewLoginTokenAuth configures and returns a LoginToken authentication instance.

func (*LoginTokenAuth) CreateToken

func (a *LoginTokenAuth) CreateToken(id int) LoginToken

CreateToken creates an in-memory login token referencing account ID. It returns a token containing a random tokenstring and expiry date.

func (*LoginTokenAuth) GetAccountID

func (a *LoginTokenAuth) GetAccountID(token string) (int, error)

GetAccountID looks up the token by tokenstring and returns the account ID or error if token not found or expired.

type Mailer

type Mailer interface {
	LoginToken(name, email string, c email.ContentLoginToken) error
}

Mailer defines methods to send account emails.

type MockAuthStore

type MockAuthStore struct {
	GetAccountFn      func(id int) (*Account, error)
	GetAccountInvoked bool

	GetAccountByEmailFn      func(email string) (*Account, error)
	GetAccountByEmailInvoked bool

	UpdateAccountFn      func(a *Account) error
	UpdateAccountInvoked bool

	GetTokenFn      func(token string) (*jwt.Token, error)
	GetTokenInvoked bool

	CreateOrUpdateTokenFn      func(t *jwt.Token) error
	CreateOrUpdateTokenInvoked bool

	DeleteTokenFn      func(t *jwt.Token) error
	DeleteTokenInvoked bool

	PurgeExpiredTokenFn      func() error
	PurgeExpiredTokenInvoked bool
}

MockAuthStore mocks AuthStorer interface.

func (*MockAuthStore) CreateOrUpdateToken

func (s *MockAuthStore) CreateOrUpdateToken(t *jwt.Token) error

CreateOrUpdateToken mock creates or updates a refresh token.

func (*MockAuthStore) DeleteToken

func (s *MockAuthStore) DeleteToken(t *jwt.Token) error

DeleteToken mock deletes a refresh token.

func (*MockAuthStore) GetAccount

func (s *MockAuthStore) GetAccount(id int) (*Account, error)

GetAccount mock returns an account by ID.

func (*MockAuthStore) GetAccountByEmail

func (s *MockAuthStore) GetAccountByEmail(email string) (*Account, error)

GetAccountByEmail mock returns an account by email.

func (*MockAuthStore) GetToken

func (s *MockAuthStore) GetToken(token string) (*jwt.Token, error)

GetToken mock returns an account and refresh token by token identifier.

func (*MockAuthStore) PurgeExpiredToken

func (s *MockAuthStore) PurgeExpiredToken() error

PurgeExpiredToken mock deletes expired refresh token.

func (*MockAuthStore) UpdateAccount

func (s *MockAuthStore) UpdateAccount(a *Account) error

UpdateAccount mock upates account data related to authentication.

type Resource

type Resource struct {
	LoginAuth *LoginTokenAuth
	TokenAuth *jwt.TokenAuth
	Store     AuthStorer
	Mailer    Mailer
}

Resource implements passwordless account authentication against a database.

func NewResource

func NewResource(authStore AuthStorer, mailer Mailer) (*Resource, error)

NewResource returns a configured authentication resource.

func (*Resource) Router

func (rs *Resource) Router() *chi.Mux

Router provides necessary routes for passwordless authentication flow.

Jump to

Keyboard shortcuts

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