Documentation
¶
Index ¶
- Variables
- func HaversineDistance(lat1, lng1, lat2, lng2 float64) float64
- func IsNewLocation(prev, curr LocationInfo, thresholdKM float64) bool
- func IsPrivateIP(ip string) bool
- type Config
- type DeviceInfo
- type GeoIPReader
- type Heimdall
- func (h *Heimdall) Close() error
- func (h *Heimdall) ExtractRequestInfo(r *http.Request) (DeviceInfo, LocationInfo, error)
- func (h *Heimdall) InvalidateSession(sessionID string) error
- func (h *Heimdall) IsSessionInvalidated(sessionID string) (bool, error)
- func (h *Heimdall) ListSessions(userID string) ([]*Session, error)
- func (h *Heimdall) RegisterSession(userID, sessionID string, device DeviceInfo, location LocationInfo, ...) (*RegisterResult, error)
- type LocationInfo
- type RegisterResult
- type Session
Constants ¶
This section is empty.
Variables ¶
var ( // ErrSessionNotFound is returned when a session does not exist. ErrSessionNotFound = errors.New("heimdall: session not found") // ErrSessionLimitExceeded is returned when the concurrent session limit is exceeded. ErrSessionLimitExceeded = errors.New("heimdall: concurrent session limit exceeded") // ErrSessionInvalidated is returned when attempting to use an invalidated session. ErrSessionInvalidated = errors.New("heimdall: session has been invalidated") // ErrGeoIPDatabaseNotConfigured is returned when GeoIP lookup is attempted // without configuring the GeoIP database path. ErrGeoIPDatabaseNotConfigured = errors.New("heimdall: GeoIP database path not configured") // ErrGeoIPLookupFailed is returned when IP geolocation lookup fails. ErrGeoIPLookupFailed = errors.New("heimdall: GeoIP lookup failed") // ErrInvalidIP is returned when an invalid IP address is provided. ErrInvalidIP = errors.New("heimdall: invalid IP address") )
Functions ¶
func HaversineDistance ¶
HaversineDistance calculates the distance in kilometers between two geographic coordinates using the Haversine formula.
func IsNewLocation ¶
func IsNewLocation(prev, curr LocationInfo, thresholdKM float64) bool
IsNewLocation returns true if the distance between two locations exceeds the given threshold in kilometers.
func IsPrivateIP ¶
IsPrivateIP returns true if the IP is in a private/reserved range.
Types ¶
type Config ¶
type Config struct {
// SessionTTL is how long sessions remain active.
// Default: 24 hours.
SessionTTL time.Duration
// InvalidationTTL is how long to remember invalidated sessions.
// This should be at least as long as SessionTTL to prevent
// invalidated sessions from being reused.
// Default: 24 hours (Same as SessionTTL).
InvalidationTTL time.Duration
// GeoIPDatabasePath is the path to MaxMind GeoLite2-City.mmdb file.
// Required for IP-based location detection.
// Download from: https://dev.maxmind.com/geoip/geolite2-free-geolocation-data
GeoIPDatabasePath string
// NewLocationThresholdKM is the distance threshold in kilometers
// for triggering a "new location" alert.
// Default: 100 km.
NewLocationThresholdKM float64
// SessionStore is the storage backend for sessions.
// Default: SQLite store (creates heimdall.db in current directory).
SessionStore store.SessionStore
// InvalidationCache is the cache for invalidated session IDs.
// Default: in-memory cache.
InvalidationCache store.InvalidationCache
// DatabasePath is the path for the default SQLite database.
// Only used if SessionStore is nil.
// Default: "heimdall.db".
DatabasePath string
}
Config contains configuration options for Heimdall.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a Config with sensible defaults.
type DeviceInfo ¶
type DeviceInfo struct {
IP string `json:"ip"`
UserAgent string `json:"user_agent"`
Browser string `json:"browser"`
OS string `json:"os"`
DeviceType string `json:"device_type"` // mobile, desktop, tablet
}
DeviceInfo contains device information extracted from the HTTP request.
func ExtractDeviceInfo ¶
func ExtractDeviceInfo(r *http.Request) DeviceInfo
ExtractDeviceInfo extracts device information from an HTTP request.
type GeoIPReader ¶
type GeoIPReader struct {
// contains filtered or unexported fields
}
GeoIPReader provides IP geolocation using MaxMind GeoLite2 database.
func NewGeoIPReader ¶
func NewGeoIPReader(dbPath string) (*GeoIPReader, error)
NewGeoIPReader opens a MaxMind GeoLite2-City database.
func (*GeoIPReader) Lookup ¶
func (r *GeoIPReader) Lookup(ip string) (*LocationInfo, error)
Lookup returns location information for an IP address.
func (*GeoIPReader) LookupWithFallback ¶
func (r *GeoIPReader) LookupWithFallback(ip string) LocationInfo
LookupWithFallback attempts IP geolocation, returning a partial result with just the IP if lookup fails.
type Heimdall ¶
type Heimdall struct {
// contains filtered or unexported fields
}
Heimdall is the main SDK interface for session management.
func New ¶
New creates a new Heimdall instance with the given configuration. If SessionStore or InvalidationCache are not provided, defaults are used: - SessionStore: SQLite (creates heimdall.db) - InvalidationCache: SQLite (uses sessions table's invalidated_at column)
func (*Heimdall) Close ¶
Close releases all resources held by Heimdall. Should be called when the application shuts down.
func (*Heimdall) ExtractRequestInfo ¶
func (h *Heimdall) ExtractRequestInfo(r *http.Request) (DeviceInfo, LocationInfo, error)
ExtractRequestInfo extracts device and location information from an HTTP request. If GeoIP is not configured, location will contain only the IP address.
func (*Heimdall) InvalidateSession ¶
InvalidateSession marks a session as invalidated. The session ID is stored in the invalidation cache with the configured TTL. The session is also deleted from the session store.
func (*Heimdall) IsSessionInvalidated ¶
IsSessionInvalidated checks if a session has been invalidated. Returns true if the session ID was explicitly invalidated and the invalidation TTL has not expired.
func (*Heimdall) ListSessions ¶
ListSessions returns all active (non-expired) sessions for a user. Sessions are ordered by creation time, newest first.
func (*Heimdall) RegisterSession ¶
func (h *Heimdall) RegisterSession( userID, sessionID string, device DeviceInfo, location LocationInfo, concurrentLimit int, ) (*RegisterResult, error)
RegisterSession registers a new session for the user.
concurrentLimit 0 means no limit. Otherwise, if the number of active sessions equals or exceeds concurrentLimit, the new session is NOT saved and LimitExceeded is set to true. The caller should then prompt the user to invalidate an existing session.
If the user is logging in from a new location (distance > NewLocationThresholdKM), IsNewLocation is set to true and PreviousLocation contains the last known location.
type LocationInfo ¶
type LocationInfo struct {
IP string `json:"ip"`
City string `json:"city"`
Country string `json:"country"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}
LocationInfo contains geographic location extracted from IP address.
type RegisterResult ¶
type RegisterResult struct {
// Session is the newly created session. Nil if LimitExceeded is true.
Session *Session `json:"session,omitempty"`
// IsNewLocation is true if the user is logging in from an unusual location.
IsNewLocation bool `json:"is_new_location"`
// PreviousLocation is the last known location for comparison.
// Only set if IsNewLocation is true.
PreviousLocation *LocationInfo `json:"previous_location,omitempty"`
// ActiveSessions contains all active sessions for this user.
ActiveSessions []*Session `json:"active_sessions"`
// LimitExceeded is true if the concurrent session limit was exceeded.
// When true, the new session was NOT saved.
LimitExceeded bool `json:"limit_exceeded"`
}
RegisterResult is returned from RegisterSession with session info and alerts.
type Session ¶
type Session struct {
SessionID string `json:"session_id"`
UserID string `json:"user_id"`
Device DeviceInfo `json:"device"`
Location LocationInfo `json:"location"`
CreatedAt time.Time `json:"created_at"`
TTLSeconds int64 `json:"ttl_seconds"`
}
Session represents an active user session.