Files
phishingclub/backend/database/campaign.go
Ronni Skansing 8bf457c592 Added webhook data level and events filtering
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
2025-12-16 22:15:57 +01:00

96 lines
3.3 KiB
Go

package database
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
const (
CAMPAIGN_TABLE = "campaigns"
)
// Campaign is gorm data model
type Campaign struct {
ID *uuid.UUID `gorm:"primary_key;not null;unique;type:uuid"`
CreatedAt *time.Time `gorm:"not null;index;"`
UpdatedAt *time.Time `gorm:"not null;index;"`
CloseAt *time.Time `gorm:"index;"`
ClosedAt *time.Time `gorm:"index;"`
AnonymizeAt *time.Time `gorm:"index;"`
AnonymizedAt *time.Time `gorm:"index;"`
SortField string `gorm:";"`
SortOrder string `gorm:";"` // 'asc,desc,random'
SendStartAt *time.Time `gorm:"index;"`
SendEndAt *time.Time `gorm:"index;"`
// ConstraintWeekDays is a binary format.
// 0b00000001 = 1 = sunday
// 0b00000010 = 2 = monday
// 0b00000100 = 4 = tuesday
// 0b00001000 = 8 = ...
// 0b00010000 = 16 =
// 0b00100000 = 32 =
// 0b01000000 = 64 =
ConstraintWeekDays *int `gorm:";"`
// hh:mm
ConstraintStartTime *string `gorm:"index;"`
// hh:mm
ConstraintEndTime *string `gorm:"index;"`
SaveSubmittedData bool `gorm:"not null;default:false"`
SaveBrowserMetadata bool `gorm:"not null;default:false"`
IsAnonymous bool `gorm:"not null;default:false"`
IsTest bool `gorm:"not null;default:false"`
Obfuscate bool `gorm:"not null;default:false"`
WebhookIncludeData string `gorm:"not null;default:'full'"`
// WebhookEvents is a binary format storing selected events as bits (10 events)
// 0 = all events (default, backward compatible)
// non-zero = only selected events trigger webhooks
// bit 0 (1): campaign_closed
// bit 1 (2): campaign_recipient_message_sent
// bit 2 (4): campaign_recipient_message_failed
// bit 3 (8): campaign_recipient_message_read
// bit 4 (16): campaign_recipient_submitted_data
// bit 5 (32): campaign_recipient_evasion_page_visited
// bit 6 (64): campaign_recipient_before_page_visited
// bit 7 (128): campaign_recipient_page_visited
// bit 8 (256): campaign_recipient_after_page_visited
// bit 9 (512): campaign_recipient_deny_page_visited
WebhookEvents int `gorm:"not null;default:0"`
// has one
CampaignTemplateID *uuid.UUID `gorm:"index;type:uuid;"`
CampaignTemplate *CampaignTemplate
// can has one
CompanyID *uuid.UUID `gorm:"index;type:uuid;index;uniqueIndex:idx_campaigns_unique_name_and_company_id;"`
Company *Company
DenyPageID *uuid.UUID `gorm:"type:uuid;index;"`
DenyPage *Page `gorm:"foreignKey:DenyPageID;references:ID"`
EvasionPageID *uuid.UUID `gorm:"type:uuid;index;"`
EvasionPage *Page `gorm:"foreignKey:EvasionPageID;references:ID"`
// NotableEventID notable event for this campaign
NotableEvent *Event `gorm:"foreignKey:NotableEventID;references:ID"`
NotableEventID *uuid.UUID `gorm:"type:uuid;index"`
WebhookID *uuid.UUID `gorm:"type:uuid;index;"`
// has many-to-many
RecipientGroups []*RecipientGroup `gorm:"many2many:campaign_recipient_groups"`
AllowDeny []*AllowDeny `gorm:"many2many:campaign_allow_denies"`
Name string `gorm:"not null;uniqueIndex:idx_campaigns_unique_name_and_company_id"`
}
func (c *Campaign) Migrate(db *gorm.DB) error {
// SQLITE
// ensure name + company id is unique
return UniqueIndexNameAndNullCompanyID(db, "campaigns")
}
func (Campaign) TableName() string {
return CAMPAIGN_TABLE
}