package apiaudit import ( "slices" "sync" "time" "git.julianfamily.org/keepassgo/internal/apitokens" ) type EventType string const ( EventApprovalRequested EventType = "approval_requested" EventApprovalAllowed EventType = "approval_allowed" EventApprovalDenied EventType = "approval_denied" EventApprovalCanceled EventType = "approval_canceled" EventApprovalTimedOut EventType = "approval_timed_out" EventTokenIssued EventType = "token_issued" EventTokenUpdated EventType = "token_updated" EventTokenRotated EventType = "token_rotated" EventTokenDisabled EventType = "token_disabled" EventTokenRevoked EventType = "token_revoked" EventTokenDeleted EventType = "token_deleted" EventAutofillFound EventType = "autofill_found" EventAutofillAmbiguous EventType = "autofill_ambiguous" EventAutofillBlocked EventType = "autofill_blocked" EventAuthRejected EventType = "auth_rejected" ) type Event struct { Type EventType At time.Time TokenID string TokenName string ClientName string Operation apitokens.Operation Resource apitokens.Resource Message string } type Log struct { mu sync.Mutex max int now func() time.Time events []Event } func New(max int) *Log { if max < 1 { max = 1 } return &Log{ max: max, now: func() time.Time { return time.Now().UTC() }, } } func (l *Log) Record(event Event) { if l == nil { return } l.mu.Lock() defer l.mu.Unlock() if event.At.IsZero() { event.At = l.now() } l.events = append([]Event{event}, l.events...) if len(l.events) > l.max { l.events = l.events[:l.max] } } func (l *Log) Events() []Event { if l == nil { return nil } l.mu.Lock() defer l.mu.Unlock() return slices.Clone(l.events) }