mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-01-27 23:46:18 +02:00
89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
package core
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/pocketbase/pocketbase/tools/security"
|
|
"github.com/pocketbase/pocketbase/tools/types"
|
|
)
|
|
|
|
type Param struct {
|
|
BaseModel
|
|
|
|
Created types.DateTime `db:"created" json:"created"`
|
|
Updated types.DateTime `db:"updated" json:"updated"`
|
|
Value types.JSONRaw `db:"value" json:"value"`
|
|
}
|
|
|
|
func (m *Param) TableName() string {
|
|
return paramsTable
|
|
}
|
|
|
|
// ReloadSettings initializes and reloads the stored application settings.
|
|
//
|
|
// If no settings were stored it will persist the current app ones.
|
|
func (app *BaseApp) ReloadSettings() error {
|
|
param := &Param{}
|
|
err := app.ModelQuery(param).Model(paramsKeySettings, param)
|
|
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
return err
|
|
}
|
|
|
|
// no settings were previously stored -> save
|
|
// (ReloadSettings() will be invoked again by a system hook after successful save)
|
|
if param.Id == "" {
|
|
// force insert in case the param entry was deleted manually after application start
|
|
app.Settings().MarkAsNew()
|
|
return app.Save(app.Settings())
|
|
}
|
|
|
|
event := new(SettingsReloadEvent)
|
|
event.App = app
|
|
|
|
return app.OnSettingsReload().Trigger(event, func(e *SettingsReloadEvent) error {
|
|
return e.App.Settings().loadParam(e.App, param)
|
|
})
|
|
}
|
|
|
|
// loadParam loads the settings from the stored param into the app ones.
|
|
//
|
|
// @todo note that the encryption may get removed in the future since it doesn't
|
|
// really accomplish much and it might be better to find a way to encrypt the backups
|
|
// or implement support for resolving env variables.
|
|
func (s *Settings) loadParam(app App, param *Param) error {
|
|
// try first without decryption
|
|
s.mu.Lock()
|
|
plainDecodeErr := json.Unmarshal(param.Value, s)
|
|
s.mu.Unlock()
|
|
|
|
// failed, try to decrypt
|
|
if plainDecodeErr != nil {
|
|
encryptionKey := os.Getenv(app.EncryptionEnv())
|
|
|
|
// load without decryption has failed and there is no encryption key to use for decrypt
|
|
if encryptionKey == "" {
|
|
return fmt.Errorf("invalid settings db data or missing encryption key %q", app.EncryptionEnv())
|
|
}
|
|
|
|
// decrypt
|
|
decrypted, decryptErr := security.Decrypt(string(param.Value), encryptionKey)
|
|
if decryptErr != nil {
|
|
return decryptErr
|
|
}
|
|
|
|
// decode again
|
|
s.mu.Lock()
|
|
decryptedDecodeErr := json.Unmarshal(decrypted, s)
|
|
s.mu.Unlock()
|
|
if decryptedDecodeErr != nil {
|
|
return decryptedDecodeErr
|
|
}
|
|
}
|
|
|
|
return s.PostScan()
|
|
}
|