magiclink

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: MIT, MIT Imports: 16 Imported by: 0

README

gomodularauth-magic-link provides passwordless authentication through secure, single-use, expiring email magic links for GoModularAuth.

Installation

go get github.com/BladiCreator/go-modular-auth/plugins/magic-link

Quick Start

package main

import (
    "log"
    "time"

    auth "github.com/BladiCreator/go-modular-auth"
    adaptermem "github.com/BladiCreator/go-modular-auth/adapters/memory"
    magiclink "github.com/BladiCreator/go-modular-auth/plugins/magic-link"
)

func main() {
    a, err := auth.New(auth.Config{
        Adapter: adaptermem.NewAdapter(),
        Cache:   adaptermem.NewCache(),
        Email:   adaptermem.NewEmail(),

        Plugins: []auth.PluginModule{
            magiclink.New(
                magiclink.WithTTL(15 * time.Minute),
                magiclink.WithBaseURL("https://myapp.com/auth/magiclink/verify"),
                magiclink.WithAllowSignUp(true),
                magiclink.WithRateLimit(magiclink.RateLimitConfig{
                    Enabled:  true,
                    Max:      5,
                    Window:   15 * time.Minute,
                    Cooldown: 60 * time.Second,
                }),
            ),
        },
    })
    if err != nil {
        log.Fatalf("failed to initialize auth: %v", err)
    }

    // Retrieve capability
    ml, err := auth.Get[magiclink.MagicLink](a)
    if err != nil {
        log.Fatalf("magiclink plugin not installed: %v", err)
    }
}

Detailed guide: doc/plugins/magic-link.md.

Documentation

Overview

Package magiclink provides passwordless authentication via signed, expiring URLs delivered by email.

Index

Constants

View Source
const (
	// EventMagicLinkRequested is emitted after a magic link has been requested and sent.
	EventMagicLinkRequested auth.EventName = "magiclink.requested"

	// EventMagicLinkConsumed is emitted after a magic link has been successfully authenticated.
	EventMagicLinkConsumed auth.EventName = "magiclink.consumed"
)

Event names published by the magic link plugin.

View Source
const AccountProvider = "magiclink"

AccountProvider is the provider name recorded when auto-creating accounts.

View Source
const Purpose verification.Purpose = "magiclink:authenticate"

Purpose is the verification token purpose used by this plugin. Tokens issued with this purpose cannot be consumed by other workflows (password reset, email verification, etc.).

Variables

View Source
var (
	// ErrEmailRequired is returned when an email is empty.
	ErrEmailRequired = errors.New("magiclink: email is required")

	// ErrInvalidEmail is returned when an email address is malformed.
	ErrInvalidEmail = errors.New("magiclink: invalid email address")

	// ErrTokenRequired is returned when attempting authentication with an empty token.
	ErrTokenRequired = errors.New("magiclink: token is required")

	// ErrInvalidToken is returned when a token is invalid, expired, already consumed, or revoked.
	// Deliberately coarse to avoid oracle attacks.
	ErrInvalidToken = errors.New("magiclink: invalid or expired token")

	// ErrUserNotFound is returned when the user associated with a token does not exist.
	ErrUserNotFound = errors.New("magiclink: user not found")

	// ErrEmailSenderRequired is returned when neither the plugin nor the host has an email sender configured.
	ErrEmailSenderRequired = errors.New("magiclink: email sender not configured")

	// ErrRateLimitExceeded is returned when the maximum number of requests for a window is exceeded.
	ErrRateLimitExceeded = errors.New("magiclink: rate limit exceeded")

	// ErrCooldownActive is returned when requesting a magic link too quickly after a previous request.
	ErrCooldownActive = errors.New("magiclink: cooldown active, please wait before requesting another link")

	// ErrSignUpDisabled is returned when attempting to consume a signup token while AllowSignUp is disabled.
	ErrSignUpDisabled = errors.New("magiclink: user sign-up is not permitted")
)

Sentinel errors returned by the magic link plugin operations.

Functions

This section is empty.

Types

type AuthenticateInput

type AuthenticateInput struct {
	// Token is the plaintext single-use token received by the user. Required.
	Token string

	// Session holds optional metadata (IP address, User Agent) recorded with the session.
	Session auth.SessionOptions
}

AuthenticateInput contains parameters for authenticating via a magic link token.

type BeforeConsumeHook

type BeforeConsumeHook func(ctx context.Context, in *AuthenticateInput) error

BeforeConsumeHook runs before consuming a magic link token. It can abort the consumption by returning an error.

type BeforeRequestHook

type BeforeRequestHook func(ctx context.Context, in *RequestInput) error

BeforeRequestHook runs before processing a magic link request. It can mutate the input or abort the request by returning an error.

type Capability

type Capability = MagicLink

Capability is an alias for MagicLink to allow idiomatic capability retrieval.

type Config

type Config struct {
	// TTL is the lifetime of an issued magic link token.
	// Default: 15 minutes.
	TTL time.Duration

	// AllowSignUp allows automatically creating a new user and account
	// if the requested email is not already registered.
	// Default: false (only existing users can authenticate).
	AllowSignUp bool

	// RevokePreviousOnRequest deletes any active magic link tokens for the subject
	// when a new magic link is requested.
	// Default: true.
	RevokePreviousOnRequest bool

	// BaseURL is an optional base URL used to construct the full magic link URL.
	// e.g. "https://myapp.com/auth/magiclink/verify".
	// The token is appended as a query parameter ("?token=").
	BaseURL string

	// RateLimit configures optional request throttling and cooldowns.
	RateLimit RateLimitConfig

	// MessageBuilder formats the transactional email.
	MessageBuilder MessageBuilder

	// EmailSender overrides the email sender configured on the host.
	EmailSender email.Sender

	// Hooks provides access to pre-request and pre-consume security hooks.
	Hooks *Hooks
}

Config configures the magic link plugin module.

type Hooks

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

Hooks manages security hooks for magic link workflows.

func NewHooks

func NewHooks() *Hooks

NewHooks returns an empty hooks manager.

func (*Hooks) BeforeConsume

func (h *Hooks) BeforeConsume(fn BeforeConsumeHook)

BeforeConsume registers a hook invoked before consuming a magic link token.

func (*Hooks) BeforeRequest

func (h *Hooks) BeforeRequest(fn BeforeRequestHook)

BeforeRequest registers a hook invoked before processing a magic link request.

type MagicLink interface {
	// Request initiates the passwordless authentication flow for the given email address.
	// If the user does not exist and AllowSignUp is false, it returns nil to prevent user enumeration.
	Request(ctx context.Context, in RequestInput) error

	// Authenticate validates and atomically consumes the single-use magic link token,
	// establishes a server-side session, and returns the authentication result.
	Authenticate(ctx context.Context, in AuthenticateInput) (*auth.AuthResult, error)

	// Revoke deletes all active magic link tokens issued for the given email address.
	Revoke(ctx context.Context, email string) error
}

MagicLink is the public capability interface exposed by this plugin. Applications retrieve it using auth.Get[magiclink.MagicLink](a) or auth.Get[plugins.MagicLink](a).

type MagicLinkConsumedPayload

type MagicLinkConsumedPayload struct {
	UserID     string    `json:"user_id"`
	Email      string    `json:"email"`
	SessionID  string    `json:"session_id"`
	ConsumedAt time.Time `json:"consumed_at"`
}

MagicLinkConsumedPayload is the non-sensitive payload published on EventMagicLinkConsumed. NOTE: Plaintext tokens and secrets are strictly excluded.

type MagicLinkRequestedPayload

type MagicLinkRequestedPayload struct {
	Email     string    `json:"email"`
	Subject   string    `json:"subject"`
	ExpiresAt time.Time `json:"expires_at"`
}

MagicLinkRequestedPayload is the non-sensitive payload published on EventMagicLinkRequested. NOTE: Plaintext tokens and secrets are strictly excluded.

type MessageBuilder

type MessageBuilder func(to string, token string, verificationURL string) email.Message

MessageBuilder builds the transactional email message sent to the user. It receives the destination email, the raw plaintext token, and the optional constructed URL.

type Module

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

Module implements auth.PluginModule for GoModularAuth using plugin-sdk.

func New

func New(opts ...Option) *Module

New constructs a new magic link plugin module.

func (*Module) ID

func (m *Module) ID() string

ID returns the module's unique identifier.

func (*Module) Init

func (m *Module) Init(h *auth.Host) error

Init initializes the plugin module on the host and registers its capability.

type Option

type Option func(*Config)

Option modifies a Config instance.

func WithAllowSignUp

func WithAllowSignUp(allow bool) Option

WithAllowSignUp toggles automatic user sign-up on magic link verification.

func WithBaseURL

func WithBaseURL(rawURL string) Option

WithBaseURL sets the base URL for constructing magic link hyperlinks.

func WithEmailSender

func WithEmailSender(sender email.Sender) Option

WithEmailSender provides an explicit email.Sender.

func WithHooks

func WithHooks(hooks *Hooks) Option

WithHooks sets custom security hooks.

func WithMessageBuilder

func WithMessageBuilder(builder MessageBuilder) Option

WithMessageBuilder configures a custom email message builder.

func WithRateLimit

func WithRateLimit(cfg RateLimitConfig) Option

WithRateLimit configures rate limiting and cooldown policies.

func WithRevokePreviousOnRequest

func WithRevokePreviousOnRequest(revoke bool) Option

WithRevokePreviousOnRequest sets whether requesting a token revokes earlier tokens.

func WithTTL

func WithTTL(ttl time.Duration) Option

WithTTL sets the lifetime of magic link tokens.

type RateLimitConfig

type RateLimitConfig struct {
	// Enabled determines whether rate limiting is active.
	Enabled bool

	// Max is the maximum number of requests allowed in Window.
	// Default: 5 requests.
	Max int

	// Window is the time window for rate limiting.
	// Default: 15 minutes.
	Window time.Duration

	// Cooldown is the minimum duration required between consecutive requests for the same email.
	// Default: 60 seconds.
	Cooldown time.Duration
}

RateLimitConfig configures request throttling.

type RequestInput

type RequestInput struct {
	// Email is the destination email address. Required.
	Email string

	// Metadata carries optional application context.
	Metadata map[string]string
}

RequestInput contains parameters for requesting a magic link.

Directories

Path Synopsis
Package cache provides rate limiting and throttling abstractions for the magic link plugin.
Package cache provides rate limiting and throttling abstractions for the magic link plugin.
Package plugins exposes the capability aliases for GoModularAuth plugins.
Package plugins exposes the capability aliases for GoModularAuth plugins.

Jump to

Keyboard shortcuts

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