added ServeEvent.InstallerFunc field

This commit is contained in:
Gani Georgiev
2024-12-30 20:26:33 +02:00
parent 0155e9333f
commit 26cb1cef37
6 changed files with 120 additions and 64 deletions

View File

@@ -5,37 +5,31 @@ import (
"errors"
"fmt"
"os"
"os/exec"
"runtime"
"strings"
"time"
"github.com/fatih/color"
"github.com/go-ozzo/ozzo-validation/v4/is"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/security"
"github.com/pocketbase/pocketbase/tools/osutils"
)
// @todo consider combining with the installer specific hooks after refactoring cmd
func loadInstaller(app core.App, dashboardURL string) error {
if !needInstallerSuperuser(app) {
return nil
}
installerRecord, err := findOrCreateInstallerSuperuser(app)
if err != nil {
return err
}
token, err := installerRecord.NewStaticAuthToken(30 * time.Minute)
// DefaultInstallerFunc is the default PocketBase installer function.
//
// It will attempt to open a link in the browser (with a short-lived auth
// token for the systemSuperuser) to the installer UI so that users can
// create their own custom superuser record.
//
// See https://github.com/pocketbase/pocketbase/discussions/5814.
func DefaultInstallerFunc(app core.App, systemSuperuser *core.Record, baseURL string) error {
token, err := systemSuperuser.NewStaticAuthToken(30 * time.Minute)
if err != nil {
return err
}
// launch url (ignore errors and always print a help text as fallback)
url := fmt.Sprintf("%s/#/pbinstal/%s", strings.TrimRight(dashboardURL, "/"), token)
_ = launchURL(url)
url := fmt.Sprintf("%s/_/#/pbinstal/%s", strings.TrimRight(baseURL, "/"), token)
_ = osutils.LaunchURL(url)
color.Magenta("\n(!) Launch the URL below in the browser if it hasn't been open already to create your first superuser account:")
color.New(color.Bold).Add(color.FgCyan).Println(url)
color.New(color.FgHiBlack, color.Italic).Printf("(you can also create your first superuser by running: %s superuser upsert EMAIL PASS)\n\n", os.Args[0])
@@ -43,6 +37,23 @@ func loadInstaller(app core.App, dashboardURL string) error {
return nil
}
func loadInstaller(
app core.App,
baseURL string,
installerFunc func(app core.App, systemSuperuser *core.Record, baseURL string) error,
) error {
if installerFunc == nil || !needInstallerSuperuser(app) {
return nil
}
superuser, err := findOrCreateInstallerSuperuser(app)
if err != nil {
return err
}
return installerFunc(app, superuser, baseURL)
}
func needInstallerSuperuser(app core.App) bool {
total, err := app.CountRecords(core.CollectionNameSuperusers, dbx.Not(dbx.HashExp{
"email": core.DefaultInstallerEmail,
@@ -65,7 +76,7 @@ func findOrCreateInstallerSuperuser(app core.App) (*core.Record, error) {
record = core.NewRecord(col)
record.SetEmail(core.DefaultInstallerEmail)
record.SetPassword(security.RandomString(30))
record.SetRandomPassword()
err = app.Save(record)
if err != nil {
@@ -75,20 +86,3 @@ func findOrCreateInstallerSuperuser(app core.App) (*core.Record, error) {
return record, nil
}
func launchURL(url string) error {
if err := is.URL.Validate(url); err != nil {
return err
}
switch runtime.GOOS {
case "darwin":
return exec.Command("open", url).Start()
case "windows":
// not sure if this is the best command but seems to be the most reliable based on the comments in
// https://stackoverflow.com/questions/3739327/launching-a-website-via-the-windows-commandline#answer-49115945
return exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
default: // linux, freebsd, etc.
return exec.Command("xdg-open", url).Start()
}
}