fix: create custom superuser setup to change new pocketbase superuser behavior

This commit is contained in:
Maxi Quoß
2024-12-29 12:00:12 +01:00
parent 6d06e5ae9b
commit 9ebe092b9d
6 changed files with 80 additions and 21 deletions

View File

@@ -216,3 +216,43 @@ func HandlerScan(e *core.RequestEvent) error {
return e.JSON(http.StatusOK, res)
}
func HandlerInitSuperuser(e *core.RequestEvent) error {
superusersCollection, err := e.App.FindCollectionByNameOrId(core.CollectionNameSuperusers)
if err != nil {
return e.NotFoundError("Failed to retrieve superusers collection", err)
}
totalSuperusers, err := e.App.CountRecords(superusersCollection)
if err != nil {
return e.InternalServerError("Failed to retrieve superusers count", err)
}
if totalSuperusers > 0 {
return e.BadRequestError("An initial superuser already exists", nil)
}
data := struct {
Email string `json:"email" form:"email"`
Password string `json:"password" form:"password"`
PasswordConfirm string `json:"password_confirm" form:"password-confirm"`
}{}
err = e.BindBody(&data)
if err != nil {
return e.BadRequestError("Failed to read request data", err)
}
if data.Password != data.PasswordConfirm {
return e.BadRequestError("Password don't match", err)
}
record := core.NewRecord(superusersCollection)
record.SetEmail(data.Email)
record.SetPassword(data.Password)
err = App.Save(record)
if err != nil {
return e.BadRequestError("Failed to create initial superuser", err)
}
return apis.RecordAuthResponse(e, record, "", nil)
}

View File

@@ -1,6 +1,7 @@
package pb
import (
"errors"
"fmt"
"io/fs"
"os"
@@ -66,6 +67,7 @@ func StartPocketBase(distDirFS fs.FS) {
se.Router.GET("/api/upsnap/reboot/{id}", HandlerReboot).Bind(RequireUpSnapPermission())
se.Router.GET("/api/upsnap/shutdown/{id}", HandlerShutdown).Bind(RequireUpSnapPermission())
se.Router.GET("/api/upsnap/scan", HandlerScan).Bind(apis.RequireSuperuserAuth())
se.Router.POST("/api/upsnap/init-superuser", HandlerInitSuperuser) // https://github.com/pocketbase/pocketbase/discussions/6198
if err := importSettings(); err != nil {
return err
@@ -115,18 +117,18 @@ func StartPocketBase(distDirFS fs.FS) {
cronjobs.SetWakeShutdownJobs(App)
}
}
return nil
return e.Next()
})
return se.Next()
})
App.OnModelAfterCreateSuccess().BindFunc(func(e *core.ModelEvent) error {
if e.Model.TableName() == "_admins" {
if e.Model.TableName() == "_superusers" {
if err := setSetupCompleted(); err != nil {
logger.Error.Println(err)
return err
}
return nil
return e.Next()
} else if e.Model.TableName() == "devices" {
// when a device is created, give the user all rights to the device he just created
deviceRec := e.Model.(*core.Record)
@@ -149,21 +151,30 @@ func StartPocketBase(distDirFS fs.FS) {
}
}
}
return nil
return e.Next()
})
App.OnModelAfterDeleteSuccess().BindFunc(func(e *core.ModelEvent) error {
if e.Model.TableName() == "_admins" {
if e.Model.TableName() == "_superusers" {
if err := setSetupCompleted(); err != nil {
logger.Error.Println(err)
return err
}
}
return nil
return e.Next()
})
// prevent new superuser bahavior introduced in pocketbase 0.23
App.OnRecordCreate(core.CollectionNameSuperusers).BindFunc(func(e *core.RecordEvent) error {
if e.Record.Email() == core.DefaultInstallerEmail {
return errors.New("skip default PocketBase installer")
}
return e.Next()
})
App.OnTerminate().BindFunc(func(e *core.TerminateEvent) error {
cronjobs.StopAll()
return nil
return e.Next()
})
if err := App.Start(); err != nil {

View File

@@ -65,10 +65,13 @@
// refresh auth token
if ($pocketbase.authStore.isSuperuser) {
await $pocketbase.admins.authRefresh().catch(() => {
$pocketbase.authStore.clear();
goto('/login');
});
await $pocketbase
.collection('_superusers')
.authRefresh()
.catch(() => {
$pocketbase.authStore.clear();
goto('/login');
});
} else {
await $pocketbase
.collection('users')

View File

@@ -95,9 +95,9 @@
function changePassword() {
fetch(
`${backendUrl}api/${$pocketbase.authStore.isSuperuser ? 'admins' : `collections/users/records`}/${
$pocketbase.authStore.record?.id
}`,
`${backendUrl}api/collections/${
$pocketbase.authStore.isSuperuser ? '_superusers' : `users`
}/records/${$pocketbase.authStore.record?.id}`,
{
method: 'PATCH',
headers: {

View File

@@ -23,7 +23,8 @@
});
function tryAdminThenUser() {
$pocketbase.admins
$pocketbase
.collection('_superusers')
.authWithPassword(form.email, form.password)
.then(() => {
goto('/');

View File

@@ -26,11 +26,14 @@
});
async function register() {
$pocketbase.admins
.create({
email: form.email,
password: form.password,
passwordConfirm: form.confirm
$pocketbase
.send('/api/upsnap/init-superuser', {
method: 'POST',
body: {
email: form.email,
password: form.password,
password_confirm: form.confirm
}
})
.then(() => {
$pocketbase
@@ -39,7 +42,8 @@
.then((data) => {
settingsPub.set(data as SettingsPublic);
});
$pocketbase.admins
$pocketbase
.collection('_superusers')
.authWithPassword(form.email, form.password)
.then(() => {
stepsCompleted = 2;