mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-01-27 23:46:18 +02:00
542 lines
11 KiB
Go
542 lines
11 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/pocketbase/pocketbase/tools/auth"
|
|
"github.com/pocketbase/pocketbase/tools/hook"
|
|
"github.com/pocketbase/pocketbase/tools/mailer"
|
|
"github.com/pocketbase/pocketbase/tools/router"
|
|
"github.com/pocketbase/pocketbase/tools/search"
|
|
"github.com/pocketbase/pocketbase/tools/subscriptions"
|
|
"golang.org/x/crypto/acme/autocert"
|
|
)
|
|
|
|
type HookTagger interface {
|
|
HookTags() []string
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
type baseModelEventData struct {
|
|
Model Model
|
|
}
|
|
|
|
func (e *baseModelEventData) Tags() []string {
|
|
if e.Model == nil {
|
|
return nil
|
|
}
|
|
|
|
if ht, ok := e.Model.(HookTagger); ok {
|
|
return ht.HookTags()
|
|
}
|
|
|
|
return []string{e.Model.TableName()}
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
type baseRecordEventData struct {
|
|
Record *Record
|
|
}
|
|
|
|
func (e *baseRecordEventData) Tags() []string {
|
|
if e.Record == nil {
|
|
return nil
|
|
}
|
|
|
|
return e.Record.HookTags()
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
type baseCollectionEventData struct {
|
|
Collection *Collection
|
|
}
|
|
|
|
func (e *baseCollectionEventData) Tags() []string {
|
|
if e.Collection == nil {
|
|
return nil
|
|
}
|
|
|
|
tags := make([]string, 0, 2)
|
|
|
|
if e.Collection.Id != "" {
|
|
tags = append(tags, e.Collection.Id)
|
|
}
|
|
|
|
if e.Collection.Name != "" {
|
|
tags = append(tags, e.Collection.Name)
|
|
}
|
|
|
|
return tags
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// App events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type BootstrapEvent struct {
|
|
hook.Event
|
|
App App
|
|
}
|
|
|
|
type TerminateEvent struct {
|
|
hook.Event
|
|
App App
|
|
IsRestart bool
|
|
}
|
|
|
|
type BackupEvent struct {
|
|
hook.Event
|
|
App App
|
|
Context context.Context
|
|
Name string // the name of the backup to create/restore.
|
|
Exclude []string // list of dir entries to exclude from the backup create/restore.
|
|
}
|
|
|
|
type ServeEvent struct {
|
|
hook.Event
|
|
App App
|
|
Router *router.Router[*RequestEvent]
|
|
Server *http.Server
|
|
CertManager *autocert.Manager
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Settings events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type SettingsListRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
|
|
Settings *Settings
|
|
}
|
|
|
|
type SettingsUpdateRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
|
|
OldSettings *Settings
|
|
NewSettings *Settings
|
|
}
|
|
|
|
type SettingsReloadEvent struct {
|
|
hook.Event
|
|
App App
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Mailer events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type MailerEvent struct {
|
|
hook.Event
|
|
App App
|
|
|
|
Mailer mailer.Mailer
|
|
Message *mailer.Message
|
|
}
|
|
|
|
type MailerRecordEvent struct {
|
|
MailerEvent
|
|
baseRecordEventData
|
|
Meta map[string]any
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Model events data
|
|
// -------------------------------------------------------------------
|
|
|
|
const (
|
|
ModelEventTypeCreate = "create"
|
|
ModelEventTypeUpdate = "update"
|
|
ModelEventTypeDelete = "delete"
|
|
ModelEventTypeValidate = "validate"
|
|
)
|
|
|
|
type ModelEvent struct {
|
|
hook.Event
|
|
App App
|
|
baseModelEventData
|
|
Context context.Context
|
|
|
|
// Could be any of the ModelEventType* constants, like:
|
|
// - create
|
|
// - update
|
|
// - delete
|
|
// - validate
|
|
Type string
|
|
}
|
|
|
|
type ModelErrorEvent struct {
|
|
ModelEvent
|
|
Error error
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Record events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type RecordEvent struct {
|
|
hook.Event
|
|
App App
|
|
baseRecordEventData
|
|
Context context.Context
|
|
|
|
// Could be any of the ModelEventType* constants, like:
|
|
// - create
|
|
// - update
|
|
// - delete
|
|
// - validate
|
|
Type string
|
|
}
|
|
|
|
type RecordErrorEvent struct {
|
|
RecordEvent
|
|
Error error
|
|
}
|
|
|
|
func syncModelEventWithRecordEvent(me *ModelEvent, re *RecordEvent) {
|
|
me.App = re.App
|
|
me.Context = re.Context
|
|
me.Type = re.Type
|
|
|
|
// @todo enable if after profiling doesn't have significant impact
|
|
// skip for now to avoid excessive checks and assume that the
|
|
// Model and the Record fields still points to the same instance
|
|
//
|
|
// if _, ok := me.Model.(*Record); ok {
|
|
// me.Model = re.Record
|
|
// } else if proxy, ok := me.Model.(RecordProxy); ok {
|
|
// proxy.SetProxyRecord(re.Record)
|
|
// }
|
|
}
|
|
|
|
func newRecordEventFromModelEvent(me *ModelEvent) (*RecordEvent, bool) {
|
|
record, ok := me.Model.(*Record)
|
|
if !ok {
|
|
proxy, ok := me.Model.(RecordProxy)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
record = proxy.ProxyRecord()
|
|
}
|
|
|
|
re := new(RecordEvent)
|
|
re.App = me.App
|
|
re.Context = me.Context
|
|
re.Type = me.Type
|
|
re.Record = record
|
|
|
|
return re, true
|
|
}
|
|
|
|
func newRecordErrorEventFromModelErrorEvent(me *ModelErrorEvent) (*RecordErrorEvent, bool) {
|
|
recordEvent, ok := newRecordEventFromModelEvent(&me.ModelEvent)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
re := new(RecordErrorEvent)
|
|
re.RecordEvent = *recordEvent
|
|
re.Error = me.Error
|
|
|
|
return re, true
|
|
}
|
|
|
|
func syncModelErrorEventWithRecordErrorEvent(me *ModelErrorEvent, re *RecordErrorEvent) {
|
|
syncModelEventWithRecordEvent(&me.ModelEvent, &re.RecordEvent)
|
|
me.Error = re.Error
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Collection events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type CollectionEvent struct {
|
|
hook.Event
|
|
App App
|
|
baseCollectionEventData
|
|
Context context.Context
|
|
|
|
// Could be any of the ModelEventType* constants, like:
|
|
// - create
|
|
// - update
|
|
// - delete
|
|
// - validate
|
|
Type string
|
|
}
|
|
|
|
type CollectionErrorEvent struct {
|
|
CollectionEvent
|
|
Error error
|
|
}
|
|
|
|
func syncModelEventWithCollectionEvent(me *ModelEvent, ce *CollectionEvent) {
|
|
me.App = ce.App
|
|
me.Context = ce.Context
|
|
me.Type = ce.Type
|
|
me.Model = ce.Collection
|
|
}
|
|
|
|
func newCollectionEventFromModelEvent(me *ModelEvent) (*CollectionEvent, bool) {
|
|
record, ok := me.Model.(*Collection)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
ce := new(CollectionEvent)
|
|
ce.App = me.App
|
|
ce.Context = me.Context
|
|
ce.Type = me.Type
|
|
ce.Collection = record
|
|
|
|
return ce, true
|
|
}
|
|
|
|
func newCollectionErrorEventFromModelErrorEvent(me *ModelErrorEvent) (*CollectionErrorEvent, bool) {
|
|
collectionevent, ok := newCollectionEventFromModelEvent(&me.ModelEvent)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
ce := new(CollectionErrorEvent)
|
|
ce.CollectionEvent = *collectionevent
|
|
ce.Error = me.Error
|
|
|
|
return ce, true
|
|
}
|
|
|
|
func syncModelErrorEventWithCollectionErrorEvent(me *ModelErrorEvent, ce *CollectionErrorEvent) {
|
|
syncModelEventWithCollectionEvent(&me.ModelEvent, &ce.CollectionEvent)
|
|
me.Error = ce.Error
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// File API events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type FileTokenRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseRecordEventData
|
|
|
|
Token string
|
|
}
|
|
|
|
type FileDownloadRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
FileField *FileField
|
|
ServedPath string
|
|
ServedName string
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Collection API events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type CollectionsListRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
|
|
Collections []*Collection
|
|
Result *search.Result
|
|
}
|
|
|
|
type CollectionsImportRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
|
|
CollectionsData []map[string]any
|
|
DeleteMissing bool
|
|
}
|
|
|
|
type CollectionRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Realtime API events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type RealtimeConnectRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
|
|
Client subscriptions.Client
|
|
|
|
// note: modifying it after the connect has no effect
|
|
IdleTimeout time.Duration
|
|
}
|
|
|
|
type RealtimeMessageEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
|
|
Client subscriptions.Client
|
|
Message *subscriptions.Message
|
|
}
|
|
|
|
type RealtimeSubscribeRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
|
|
Client subscriptions.Client
|
|
Subscriptions []string
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Record CRUD API events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type RecordsListRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
// @todo consider removing and maybe add as generic to the search.Result?
|
|
Records []*Record
|
|
Result *search.Result
|
|
}
|
|
|
|
type RecordRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
}
|
|
|
|
type RecordEnrichEvent struct {
|
|
hook.Event
|
|
App App
|
|
baseRecordEventData
|
|
|
|
RequestInfo *RequestInfo
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Auth Record API events data
|
|
// -------------------------------------------------------------------
|
|
|
|
type RecordCreateOTPRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
Password string
|
|
}
|
|
|
|
type RecordAuthWithOTPRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
OTP *OTP
|
|
}
|
|
|
|
type RecordAuthRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
Token string
|
|
Meta any
|
|
AuthMethod string
|
|
}
|
|
|
|
type RecordAuthWithPasswordRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
Identity string
|
|
IdentityField string
|
|
Password string
|
|
}
|
|
|
|
type RecordAuthWithOAuth2RequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
ProviderName string
|
|
ProviderClient auth.Provider
|
|
Record *Record
|
|
OAuth2User *auth.AuthUser
|
|
CreateData map[string]any
|
|
IsNewRecord bool
|
|
}
|
|
|
|
type RecordAuthRefreshRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
}
|
|
|
|
type RecordRequestPasswordResetRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
}
|
|
|
|
type RecordConfirmPasswordResetRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
}
|
|
|
|
type RecordRequestVerificationRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
}
|
|
|
|
type RecordConfirmVerificationRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
}
|
|
|
|
type RecordRequestEmailChangeRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
NewEmail string
|
|
}
|
|
|
|
type RecordConfirmEmailChangeRequestEvent struct {
|
|
hook.Event
|
|
*RequestEvent
|
|
baseCollectionEventData
|
|
|
|
Record *Record
|
|
NewEmail string
|
|
}
|