auth

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2024 License: MIT Imports: 20 Imported by: 0

README

FSA

F***ing Simple Auth. A simple authentication library for Go.

Send email verification codes. Get JWT tokens.

Usage

  • Create a new instance of the authenticator
    • New() takes in a Config (defined in auth.go), a database connection (for code storage), a user creator, a mailer, and a Go Template - these should implement IAuthDb, IUserCreator, and ICodeSender
    • NewWithMemDbAndDefaultTemplate() takes in a Config, a user creator and a mailer, and uses an in-memory database, and the default template
  • There is a chi middleware which can be wired up with the Config (call NewAuthMiddleware) to verify JWTs
  • LoginStep1SendVerificationCode sends a verification code to the passed email address
  • LoginStep2ConfirmCode takes in an email and a code, calls the CreatUserIfNotExists on IUserCreator, and returns a JWT if the code is accepted
    • This JWT contains AccessToken and RefreshToken which both contain email and expiry claims only (This is deliberately kept lightweight)

IAuthDb

This is an interface which should satisfy the requirement for storing and retrieving codes. Out of the box you can use NewWithMemDbAndDefaultTemplate() to get an in-memory implementation.

IUserCreator

This is an interface which should satisfy the requirement for creating a user in your system, if they don't already exist.

ICodeSender

This is an interface which should satisfy the requirement for sending a code to a user, for example it could send to a queue, or via SMTP/SMS API.

IEmailValidator

This is an interface which should satisfy the requirement for validating the email address provided by the user, for example email@domain..com would not be a valid email where as email@domain.com would be valid.

Todo

  • Pass in CORS config to the middleware
  • Store/invalidate used refresh tokens
  • Add a simple sender implementation for SMTP (Mailhog is a good option for testing)

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrorAuthHeaderMissing = errors.New("authorization header is missing")
	ErrorInvalidAuthHeader = errors.New("invalid authorization header format")
)

Functions

func WriteErr

func WriteErr(w http.ResponseWriter, err error, code int)

func WriteJSON

func WriteJSON(w http.ResponseWriter, v interface{})

Types

type Auth

type Auth struct {
	Db     IAuthDb
	Sender ICodeSender
	Uc     IUserCreator
	Ev     IEmailValidator
	Uiv    IUserIdentityVerifier

	EmailTemplate *template.Template

	Cfg *Config
}

func NewWithMemDbAndDefaultTemplate

func NewWithMemDbAndDefaultTemplate(sender ICodeSender, uc IUserCreator, cfg *Config) *Auth

func (*Auth) LoginStep1SendVerificationCode

func (a *Auth) LoginStep1SendVerificationCode(ctx context.Context, email, returnUrl string) error

func (*Auth) LoginStep2ConfirmCode

func (a *Auth) LoginStep2ConfirmCode(ctx context.Context, email string, code string) (bool, *TokenResponse, error)

func (*Auth) ParseTemplate

func (a *Auth) ParseTemplate(link, code string) string

func (*Auth) RefreshToken

func (a *Auth) RefreshToken(ctx context.Context, rt string) (*TokenResponse, error)

type AuthMiddleware

type AuthMiddleware struct {
	Cfg *Config
}

func NewChiMiddleware

func NewChiMiddleware(cfg *Config) *AuthMiddleware

func (*AuthMiddleware) VerifyAuthenticationToken

func (am *AuthMiddleware) VerifyAuthenticationToken(next http.Handler) http.Handler

type Code

type Code struct {
	Code      string
	ExpiresAt time.Time
}

type Config

type Config struct {
	AppName string

	CodeValidityPeriod         time.Duration
	AccessTokenValidityPeriod  time.Duration
	RefreshTokenValidityPeriod time.Duration

	AccessTokenSecret  string
	RefreshTokenSecret string

	RateLimitPerSecond int

	ReturnUrls []string

	UseIdentity bool
}

type Db

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

func NewMemDb

func NewMemDb() *Db

func (*Db) GetVerificationCode

func (d *Db) GetVerificationCode(email string) (string, time.Time, error)

func (*Db) RemoveVerificationCode

func (d *Db) RemoveVerificationCode(email string) error

func (*Db) StoreVerificationCode

func (d *Db) StoreVerificationCode(email string, code string, expiresAt time.Time) error

type EmailData

type EmailData struct {
	Link       string
	Code       string
	AppName    string
	AppNameL1  string
	AppNameEnd string
}

type EmailValidator

type EmailValidator struct {
	Ev IEmailValidator
}

func NewEmailValidator

func NewEmailValidator() *EmailValidator

func (*EmailValidator) Validate

func (ev *EmailValidator) Validate(email string) bool

type ErrResponse

type ErrResponse struct {
	Error string `json:"error"`
}

type Handler

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

func NewHandler

func NewHandler(r chi.Router, auth *Auth) *Handler

func (*Handler) ConfirmCode

func (h *Handler) ConfirmCode(w http.ResponseWriter, r *http.Request)

func (*Handler) Login

func (h *Handler) Login(w http.ResponseWriter, r *http.Request)

func (*Handler) RefreshToken

func (h *Handler) RefreshToken(w http.ResponseWriter, r *http.Request)

func (*Handler) SetupRoutes

func (h *Handler) SetupRoutes(router chi.Router)

type IAuthDb

type IAuthDb interface {
	StoreVerificationCode(email string, code string, expiresAt time.Time) error
	GetVerificationCode(email string) (code string, expiresAt time.Time, error error)
	RemoveVerificationCode(email string) error
}

type ICodeSender

type ICodeSender interface {
	Send(to string, subject string, body string) error
}

type IEmailValidator

type IEmailValidator interface {
	Validate(email string) bool
}

type IUserCreator

type IUserCreator interface {
	CreateEmailVerifiedUserIfNotExists(ctx context.Context, email string) (newUser bool, err error)
}

type IUserIdentityVerifier

type IUserIdentityVerifier interface {
	CanLogin(email string) (bool, string, error)
}

type Key

type Key string
const ClaimsKey Key = "claims"
const UserEmailKey Key = "userEmail"

type Token

type Token struct {
	Token       string
	TokenExpiry time.Time
}

type TokenResponse

type TokenResponse struct {
	AccessToken  *Token
	RefreshToken *Token
}

type UserIdentityVerifier

type UserIdentityVerifier struct {
	Uv IUserIdentityVerifier
	// contains filtered or unexported fields
}

func NewUserIdentityVerifier

func NewUserIdentityVerifier() *UserIdentityVerifier

func (*UserIdentityVerifier) CanLogin

func (uv *UserIdentityVerifier) CanLogin(email string) (bool, string, error)

func (*UserIdentityVerifier) SetEmail

func (uv *UserIdentityVerifier) SetEmail(email string)

Jump to

Keyboard shortcuts

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