Files
Charon/backend/internal/models/emergency_token.go
2026-03-04 18:34:49 +00:00

42 lines
1.5 KiB
Go

package models
import (
"time"
)
// EmergencyToken stores metadata for database-backed emergency access tokens.
// Tokens are stored as bcrypt hashes for security.
type EmergencyToken struct {
ID uint `json:"-" gorm:"primaryKey"`
TokenHash string `json:"-" gorm:"type:text;not null"` // bcrypt hash, never exposed in JSON
CreatedAt time.Time `json:"created_at"`
ExpiresAt *time.Time `json:"expires_at"` // NULL = never expires
ExpirationPolicy string `json:"expiration_policy" gorm:"type:text;not null"` // "30_days", "60_days", "90_days", "custom", "never"
CreatedByUserID *uint `json:"created_by_user_id"` // User who generated token (NULL for env var tokens)
LastUsedAt *time.Time `json:"last_used_at"`
UseCount int `json:"use_count" gorm:"default:0"`
UpdatedAt time.Time `json:"updated_at"`
}
// TableName specifies the table name for GORM
func (EmergencyToken) TableName() string {
return "emergency_tokens"
}
// IsExpired checks if the token has expired
func (et *EmergencyToken) IsExpired() bool {
if et.ExpiresAt == nil {
return false // Never expires
}
return time.Now().After(*et.ExpiresAt)
}
// DaysUntilExpiration returns the number of days until expiration (negative if expired)
func (et *EmergencyToken) DaysUntilExpiration() int {
if et.ExpiresAt == nil {
return -1 // Special value for "never expires"
}
duration := time.Until(*et.ExpiresAt)
return int(duration.Hours() / 24)
}