Skip to content

Commit

Permalink
fix: create custom superuser setup to change new pocketbase superuser…
Browse files Browse the repository at this point in the history
… behavior
  • Loading branch information
seriousm4x committed Dec 29, 2024
1 parent 6d06e5a commit 9ebe092
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 21 deletions.
40 changes: 40 additions & 0 deletions backend/pb/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
25 changes: 18 additions & 7 deletions backend/pb/pb.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pb

import (
"errors"
"fmt"
"io/fs"
"os"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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 {
Expand Down
11 changes: 7 additions & 4 deletions frontend/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/routes/account/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/routes/login/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
});
function tryAdminThenUser() {
$pocketbase.admins
$pocketbase
.collection('_superusers')
.authWithPassword(form.email, form.password)
.then(() => {
goto('/');
Expand Down
16 changes: 10 additions & 6 deletions frontend/src/routes/welcome/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -39,7 +42,8 @@
.then((data) => {
settingsPub.set(data as SettingsPublic);
});
$pocketbase.admins
$pocketbase
.collection('_superusers')
.authWithPassword(form.email, form.password)
.then(() => {
stepsCompleted = 2;
Expand Down

0 comments on commit 9ebe092

Please sign in to comment.