Documentation
¶
Index ¶
- Constants
- Variables
- func SignCookieValue(tokenValue, secret string) string
- func VerifyCookieValue(signedCookieVal, secret string) (string, error)
- type Config
- type DeviceSession
- type ListDeviceSessionsEventPayload
- type ListDeviceSessionsParams
- type ListDeviceSessionsResult
- type MultiSessionConfigInfo
- type Option
- type Plugin
- func (p *Plugin) AfterSessionCreated(ctx context.Context, w http.ResponseWriter, r *http.Request, ...) error
- func (p *Plugin) AfterSignOut(ctx context.Context, w http.ResponseWriter, r *http.Request) error
- func (p *Plugin) Config() Config
- func (p *Plugin) ExpireCookie(w http.ResponseWriter, cookieName string)
- func (p *Plugin) ExpireMainSessionCookie(w http.ResponseWriter)
- func (p *Plugin) ExtractMainSessionToken(r *http.Request) string
- func (p *Plugin) ExtractMultiSessionTokens(r *http.Request) []string
- func (p *Plugin) GetConfigInfo() MultiSessionConfigInfo
- func (p *Plugin) GetMultiCookieName(token string) string
- func (p *Plugin) ID() string
- func (p *Plugin) Init(ctx *plugin.Context) error
- func (p *Plugin) ListDeviceSessions(ctx context.Context, params ListDeviceSessionsParams) (*ListDeviceSessionsResult, error)
- func (p *Plugin) Repository() Repository
- func (p *Plugin) RevokeAllSessions(ctx context.Context, params RevokeAllSessionsParams) (*RevokeAllSessionsResult, error)
- func (p *Plugin) RevokeDeviceSession(ctx context.Context, params RevokeDeviceSessionParams) (*RevokeDeviceSessionResult, error)
- func (p *Plugin) RevokeOtherSessions(ctx context.Context, params RevokeOtherSessionsParams) (*RevokeOtherSessionsResult, error)
- func (p *Plugin) SetActiveSession(ctx context.Context, params SetActiveSessionParams) (*SetActiveSessionResult, error)
- func (p *Plugin) SetMainSessionCookie(w http.ResponseWriter, token string, expiresAt time.Time)
- func (p *Plugin) SetMultiSessionCookie(w http.ResponseWriter, token string, expiresAt time.Time)
- type Repository
- type RevokeAllSessionsParams
- type RevokeAllSessionsResult
- type RevokeDeviceSessionEventPayload
- type RevokeDeviceSessionParams
- type RevokeDeviceSessionResult
- type RevokeOtherSessionsParams
- type RevokeOtherSessionsResult
- type SessionActivatedCallback
- type SessionCreatedEventPayload
- type SessionRevokedCallback
- type SetActiveSessionEventPayload
- type SetActiveSessionParams
- type SetActiveSessionResult
- type SignOutEventPayload
- type StatusResponse
Constants ¶
const ( // EventListDeviceSessionsBefore is emitted before querying device sessions for a set of tokens. EventListDeviceSessionsBefore = "multisession:list:before" // EventListDeviceSessionsAfter is emitted after successfully retrieving device sessions. EventListDeviceSessionsAfter = "multisession:list:after" // EventSetActiveSessionBefore is emitted before establishing a session as the primary active session. EventSetActiveSessionBefore = "multisession:set_active:before" // EventSetActiveSessionAfter is emitted after successfully activating a device session. EventSetActiveSessionAfter = "multisession:set_active:after" // EventRevokeDeviceSessionBefore is emitted before revoking a device session. EventRevokeDeviceSessionBefore = "multisession:revoke:before" // EventRevokeDeviceSessionAfter is emitted after successfully revoking a device session. EventRevokeDeviceSessionAfter = "multisession:revoke:after" // EventSessionCreated is emitted after a new multi-session is registered on a device. EventSessionCreated = "multisession:session_created" // EventSignOut is emitted when all multi-sessions registered on a device are mass-revoked during sign-out. EventSignOut = "multisession:sign_out" )
const PluginID = "multi-session"
PluginID is the unique string identifier for the MultiSession plugin ("multi-session").
Variables ¶
var ( // ErrInvalidSessionToken indicates that the provided session token or cookie signature is invalid. ErrInvalidSessionToken = errors.New("multisession: invalid session token") // ErrSessionNotFound indicates that the requested session does not exist or has expired. ErrSessionNotFound = errors.New("multisession: session not found") // ErrSecretRequired indicates that a cryptographic secret is required to sign or verify cookies. ErrSecretRequired = errors.New("multisession: secret key is required") // ErrInvalidSignature indicates an invalid or forged HMAC signature on a multi-session cookie. ErrInvalidSignature = errors.New("multisession: invalid cookie signature") )
Functions ¶
func SignCookieValue ¶
SignCookieValue generates a signed cookie string in the format "<token>.<signature>" using HMAC-SHA256.
func VerifyCookieValue ¶
VerifyCookieValue verifies an HMAC-SHA256 signature and returns the raw token value. It supports optional "s:" prefix used by TypeScript signed cookie implementations.
Types ¶
type Config ¶
type Config struct {
// MaximumSessions specifies the maximum number of active concurrent multi-sessions allowed on a single device.
// Default: 5
MaximumSessions int
// CookiePrefix defines the prefix for multi-session cookies.
// Default: "modular-auth"
CookiePrefix string
// Secret is the HMAC SHA-256 secret key used for signing and verifying multi-session cookies.
Secret string
// OnSessionActivated is an optional callback triggered after a session is set active.
OnSessionActivated SessionActivatedCallback
// OnSessionRevoked is an optional callback triggered after a session is revoked.
OnSessionRevoked SessionRevokedCallback
}
Config defines the configuration parameters for the MultiSession plugin.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a Config struct initialized with recommended default values.
type DeviceSession ¶
type DeviceSession struct {
Session entity.Session `json:"session"`
User entity.User `json:"user"`
IsActive bool `json:"isActive"`
}
DeviceSession pairs a Session entity with its corresponding User entity for device session listing, including a flag indicating whether it is the currently active primary session.
type ListDeviceSessionsEventPayload ¶
type ListDeviceSessionsEventPayload struct {
Params *ListDeviceSessionsParams
Result *ListDeviceSessionsResult
Extra map[string]any
}
ListDeviceSessionsEventPayload contains parameter and result data associated with device session listing lifecycle events.
type ListDeviceSessionsParams ¶
type ListDeviceSessionsParams struct {
// Tokens is the slice of verified multi-session tokens present on the client device.
Tokens []string `json:"tokens"`
// ActiveToken optionally specifies the raw token string of the currently active primary session.
ActiveToken string `json:"activeToken,omitempty"`
}
ListDeviceSessionsParams contains input parameters for listing device sessions.
type ListDeviceSessionsResult ¶
type ListDeviceSessionsResult struct {
// DeviceSessions is the slice of valid, non-expired sessions on the device.
DeviceSessions []DeviceSession `json:"deviceSessions"`
// TotalCount is the total number of valid multi-sessions found.
TotalCount int `json:"totalCount"`
// ActiveSession points to the currently active primary session on the device, if present in the list.
ActiveSession *DeviceSession `json:"activeSession,omitempty"`
}
ListDeviceSessionsResult contains the list of active device sessions and metadata.
type MultiSessionConfigInfo ¶
type MultiSessionConfigInfo struct {
MaximumSessions int `json:"maximumSessions"`
CookiePrefix string `json:"cookiePrefix"`
}
MultiSessionConfigInfo represents public metadata regarding active plugin configuration.
type Option ¶
type Option func(*Config)
Option defines a functional option type for configuring the plugin.
func WithCookiePrefix ¶
WithCookiePrefix configures the custom prefix used for multi-session cookies.
func WithMaximumSessions ¶
WithMaximumSessions configures the maximum session limit per device.
func WithOnSessionActivated ¶
func WithOnSessionActivated(fn SessionActivatedCallback) Option
WithOnSessionActivated sets an optional callback executed after a session is set active.
func WithOnSessionRevoked ¶
func WithOnSessionRevoked(fn SessionRevokedCallback) Option
WithOnSessionRevoked sets an optional callback executed after a session is revoked.
func WithSecret ¶
WithSecret configures the cryptographic secret key used for HMAC cookie signature verification.
type Plugin ¶
type Plugin struct {
// contains filtered or unexported fields
}
Plugin implements the MultiSession plugin for go-modular-auth.
func New ¶
func New(repo Repository, opts ...Option) *Plugin
New instantiates a new MultiSession plugin configured with the given repository and options.
func (*Plugin) AfterSessionCreated ¶
func (p *Plugin) AfterSessionCreated(ctx context.Context, w http.ResponseWriter, r *http.Request, newSession *entity.Session) error
AfterSessionCreated runs after a new session is created to enforce session limits and emit multi-session cookies.
func (*Plugin) AfterSignOut ¶
AfterSignOut runs during sign-out to perform mass revocation of all multi-sessions registered on the device.
func (*Plugin) ExpireCookie ¶
func (p *Plugin) ExpireCookie(w http.ResponseWriter, cookieName string)
ExpireCookie marks a specified cookie name for immediate expiration in an HTTP response.
func (*Plugin) ExpireMainSessionCookie ¶
func (p *Plugin) ExpireMainSessionCookie(w http.ResponseWriter)
ExpireMainSessionCookie marks the primary session cookie for immediate expiration in an HTTP response.
func (*Plugin) ExtractMainSessionToken ¶
ExtractMainSessionToken extracts and verifies the primary session token cookie from an incoming HTTP request.
func (*Plugin) ExtractMultiSessionTokens ¶
ExtractMultiSessionTokens parses and verifies all multi-session cookies present on an incoming HTTP request.
func (*Plugin) GetConfigInfo ¶
func (p *Plugin) GetConfigInfo() MultiSessionConfigInfo
GetConfigInfo returns a MultiSessionConfigInfo struct containing active public configuration settings.
func (*Plugin) GetMultiCookieName ¶
GetMultiCookieName formats and sanitizes the multi-session cookie name for a given token string.
func (*Plugin) ListDeviceSessions ¶
func (p *Plugin) ListDeviceSessions(ctx context.Context, params ListDeviceSessionsParams) (*ListDeviceSessionsResult, error)
ListDeviceSessions queries and returns all valid, non-expired device sessions for the given parameters.
func (*Plugin) Repository ¶
func (p *Plugin) Repository() Repository
Repository returns the active storage repository instance.
func (*Plugin) RevokeAllSessions ¶
func (p *Plugin) RevokeAllSessions(ctx context.Context, params RevokeAllSessionsParams) (*RevokeAllSessionsResult, error)
RevokeAllSessions revokes all multi-sessions registered on a device.
func (*Plugin) RevokeDeviceSession ¶
func (p *Plugin) RevokeDeviceSession(ctx context.Context, params RevokeDeviceSessionParams) (*RevokeDeviceSessionResult, error)
RevokeDeviceSession revokes a single session, all sessions, or all other non-active sessions based on params.
func (*Plugin) RevokeOtherSessions ¶
func (p *Plugin) RevokeOtherSessions(ctx context.Context, params RevokeOtherSessionsParams) (*RevokeOtherSessionsResult, error)
RevokeOtherSessions revokes all device sessions except the currently active primary session.
func (*Plugin) SetActiveSession ¶
func (p *Plugin) SetActiveSession(ctx context.Context, params SetActiveSessionParams) (*SetActiveSessionResult, error)
SetActiveSession activates a target device session specified in parameters.
func (*Plugin) SetMainSessionCookie ¶
SetMainSessionCookie writes the primary signed session cookie to an HTTP response.
func (*Plugin) SetMultiSessionCookie ¶
SetMultiSessionCookie writes a signed multi-session cookie to an HTTP response.
type Repository ¶
type Repository interface {
// GetSessionByToken retrieves a session entity by its unique session token string.
//
// Function:
// Used during session validation and active device count evaluation.
//
// Storage:
// Database (GORM / SQL) - Query sessions table by token column index.
//
// Arguments:
// - ctx: Request cancellation context.
// - token: Session token string.
//
// Returns:
// - *entity.Session: Matching session entity if found.
// - error: Nil on success, or database error.
//
// Example SQL:
// SELECT id, user_id, token, expires_at, created_at, updated_at FROM sessions WHERE token = $1 LIMIT 1;
GetSessionByToken(ctx context.Context, token string) (*entity.Session, error)
// GetUserByID retrieves a user entity by its unique user ID.
//
// Function:
// Used to resolve user details linked to active multi-session tokens.
//
// Storage:
// Database (GORM / SQL) - Primary key lookup on users table.
//
// Arguments:
// - ctx: Request cancellation context.
// - id: Unique user primary key ID.
//
// Returns:
// - *entity.User: Matching user entity if found.
// - error: Nil on success, or database error.
//
// Example SQL:
// SELECT id, email, name, avatar, role, created_at, updated_at FROM users WHERE id = $1 LIMIT 1;
GetUserByID(ctx context.Context, id string) (*entity.User, error)
// DeleteSession removes a single session by token string.
//
// Function:
// Called during individual session revocation or logout.
//
// Storage:
// Database (GORM / SQL) - Delete row matching token.
//
// Arguments:
// - ctx: Request cancellation context.
// - token: Target session token string to revoke.
//
// Returns:
// - error: Nil on success, or database error.
//
// Example SQL:
// DELETE FROM sessions WHERE token = $1;
DeleteSession(ctx context.Context, token string) error
// DeleteSessions removes multiple sessions by token strings.
//
// Function:
// Called during mass revocation or session limit enforcement.
//
// Storage:
// Database (GORM / SQL) - Batch delete rows where token IN ($1, $2, ...).
//
// Arguments:
// - ctx: Request cancellation context.
// - tokens: Slice of session token strings to revoke.
//
// Returns:
// - error: Nil on success, or database error.
//
// Example SQL:
// DELETE FROM sessions WHERE token IN ($1, $2, $3);
DeleteSessions(ctx context.Context, tokens []string) error
// FindSessionsByTokens returns all valid sessions and corresponding users for a given slice of session tokens.
//
// Function:
// Called during multi-session cookie evaluation to list all active accounts on a device.
//
// Storage:
// Database (GORM / SQL) - Join sessions and users where token IN ($1, $2, ...).
//
// Arguments:
// - ctx: Request cancellation context.
// - tokens: Slice of multi-session token strings.
//
// Returns:
// - []*entity.Session: List of active session entities.
// - []*entity.User: List of corresponding user entities.
// - error: Nil on success, or database error.
//
// Example SQL:
// SELECT s.id, s.user_id, s.token, s.expires_at, u.email, u.name FROM sessions s JOIN users u ON s.user_id = u.id WHERE s.token IN ($1, $2);
FindSessionsByTokens(ctx context.Context, tokens []string) ([]*entity.Session, []*entity.User, error)
}
Repository defines data access contract required by the MultiSession plugin. Implement this interface on your custom database adapter (e.g. PostgreSQL, MySQL, SQLite, GORM).
Implementation Example (GORM / database/sql): ¶
type GormMultiSessionRepository struct {
db *gorm.DB
}
func (r *GormMultiSessionRepository) GetSessionByToken(ctx context.Context, token string) (*entity.Session, error) {
var s entity.Session
if err := r.db.WithContext(ctx).Where("token = ?", token).First(&s).Error; err != nil {
return nil, err
}
return &s, nil
}
type RevokeAllSessionsParams ¶
type RevokeAllSessionsParams struct {
// DeviceTokens specifies all verified multi-session tokens present on the device.
DeviceTokens []string `json:"deviceTokens"`
}
RevokeAllSessionsParams contains input parameters for revoking all sessions on a device.
type RevokeAllSessionsResult ¶
type RevokeAllSessionsResult struct {
// Status indicates if the revocation succeeded.
Status bool `json:"status"`
// RevokedTokens is the list of all tokens removed from the database.
RevokedTokens []string `json:"revokedTokens"`
// Count is the number of sessions revoked.
Count int `json:"count"`
}
RevokeAllSessionsResult contains the output data after revoking all sessions on a device.
type RevokeDeviceSessionEventPayload ¶
type RevokeDeviceSessionEventPayload struct {
Params *RevokeDeviceSessionParams
Result *RevokeDeviceSessionResult
Extra map[string]any
}
RevokeDeviceSessionEventPayload contains parameter and result data associated with session revocation lifecycle events.
type RevokeDeviceSessionParams ¶
type RevokeDeviceSessionParams struct {
// SessionToken specifies the target session token to revoke.
SessionToken string `json:"sessionToken,omitempty"`
// RevokeAll if true indicates all device sessions should be revoked.
RevokeAll bool `json:"revokeAll,omitempty"`
// RevokeOther if true indicates all device sessions EXCEPT the active session should be revoked.
RevokeOther bool `json:"revokeOther,omitempty"`
// DeviceTokens specifies the list of all multi-session tokens registered on the device.
DeviceTokens []string `json:"deviceTokens,omitempty"`
// ActiveTokenInReq specifies the token of the session currently marked as active in the request.
ActiveTokenInReq string `json:"activeTokenInReq,omitempty"`
}
RevokeDeviceSessionParams contains input parameters for revoking a single session, all sessions, or all other sessions.
type RevokeDeviceSessionResult ¶
type RevokeDeviceSessionResult struct {
// Status indicates if the revocation operation succeeded.
Status bool `json:"status"`
// RevokedToken contains the single token revoked (if single session revocation).
RevokedToken string `json:"revokedToken,omitempty"`
// RevokedTokens contains the list of all tokens revoked during mass/other revocation.
RevokedTokens []string `json:"revokedTokens,omitempty"`
// WasActive indicates whether the revoked session was the currently active session.
WasActive bool `json:"wasActive"`
// NewActiveSession points to the next available session to set as active, if applicable.
NewActiveSession *entity.Session `json:"newActiveSession,omitempty"`
// ClearActiveSession indicates whether the primary session cookie should be cleared.
ClearActiveSession bool `json:"clearActiveSession,omitempty"`
}
RevokeDeviceSessionResult contains the output data after revoking one or more device sessions.
type RevokeOtherSessionsParams ¶
type RevokeOtherSessionsParams struct {
// DeviceTokens specifies all verified multi-session tokens present on the device.
DeviceTokens []string `json:"deviceTokens"`
// ActiveToken specifies the token of the currently active session to keep.
ActiveToken string `json:"activeToken"`
}
RevokeOtherSessionsParams contains input parameters for revoking all device sessions EXCEPT the active session.
type RevokeOtherSessionsResult ¶
type RevokeOtherSessionsResult struct {
// Status indicates if the revocation succeeded.
Status bool `json:"status"`
// RevokedTokens is the list of non-active tokens removed from the database.
RevokedTokens []string `json:"revokedTokens"`
// Count is the number of non-active sessions revoked.
Count int `json:"count"`
}
RevokeOtherSessionsResult contains the output data after revoking all other sessions.
type SessionActivatedCallback ¶
type SessionActivatedCallback func(ctx context.Context, res *SetActiveSessionResult) error
SessionActivatedCallback is invoked whenever a device session is set active.
type SessionCreatedEventPayload ¶
SessionCreatedEventPayload contains entity data associated with multi-session creation events.
type SessionRevokedCallback ¶
type SessionRevokedCallback func(ctx context.Context, res *RevokeDeviceSessionResult) error
SessionRevokedCallback is invoked whenever a device session is revoked.
type SetActiveSessionEventPayload ¶
type SetActiveSessionEventPayload struct {
Params *SetActiveSessionParams
Result *SetActiveSessionResult
Extra map[string]any
}
SetActiveSessionEventPayload contains parameter and result data associated with session activation lifecycle events.
type SetActiveSessionParams ¶
type SetActiveSessionParams struct {
// SessionToken specifies the target session token to set as active.
SessionToken string `json:"sessionToken"`
}
SetActiveSessionParams contains input parameters for establishing an active device session.
type SetActiveSessionResult ¶
type SetActiveSessionResult struct {
// DeviceSession holds the newly activated session and user details.
DeviceSession DeviceSession `json:"deviceSession"`
// ActiveToken holds the verified token string of the active session.
ActiveToken string `json:"activeToken"`
// ExpiresAt specifies when the active session expires.
ExpiresAt time.Time `json:"expiresAt"`
// Status indicates if the activation operation succeeded.
Status bool `json:"status"`
}
SetActiveSessionResult contains the output data after activating a session.
type SignOutEventPayload ¶
SignOutEventPayload contains revoked token data associated with mass sign-out events.
type StatusResponse ¶
type StatusResponse struct {
Status bool `json:"status"`
}
StatusResponse represents a simple boolean status response payload.