lock the _mfas and _otps delete api rule, fixed flaky tests, fixed jsvm types example
This commit is contained in:
parent
0b7741f1f7
commit
8c45d4d92d
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -1,3 +1,19 @@
|
||||||
|
## v0.23.0-rc8 (WIP)
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> **This is a prerelease intended for test and experimental purposes only!**
|
||||||
|
|
||||||
|
- Lock the `_otps` and `_mfas` system collections Delete API rule for superusers only.
|
||||||
|
|
||||||
|
- Reassign in the JSVM executors the global `$app` variable with the hook scoped `e.app` value to minimize the risk of a deadlock when a hook or middleware is wrapped in a transaction.
|
||||||
|
|
||||||
|
- Reuse the OAuth2 created user record pointer to ensure that all its following hooks operate on the same record instance.
|
||||||
|
|
||||||
|
- Added tags support for the `OnRecordFileToken` hook.
|
||||||
|
|
||||||
|
- Added more detailed godoc for the collection fields and `core.App`.
|
||||||
|
|
||||||
|
|
||||||
## v0.23.0-rc7
|
## v0.23.0-rc7
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
|
|
|
@ -170,7 +170,7 @@ func TestRecordCrudMFADelete(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ExpectedStatus: 404,
|
ExpectedStatus: 403,
|
||||||
ExpectedContent: []string{`"data":{}`},
|
ExpectedContent: []string{`"data":{}`},
|
||||||
ExpectedEvents: map[string]int{"*": 0},
|
ExpectedEvents: map[string]int{"*": 0},
|
||||||
},
|
},
|
||||||
|
@ -187,7 +187,7 @@ func TestRecordCrudMFADelete(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ExpectedStatus: 404,
|
ExpectedStatus: 403,
|
||||||
ExpectedContent: []string{`"data":{}`},
|
ExpectedContent: []string{`"data":{}`},
|
||||||
ExpectedEvents: map[string]int{"*": 0},
|
ExpectedEvents: map[string]int{"*": 0},
|
||||||
},
|
},
|
||||||
|
@ -204,6 +204,23 @@ func TestRecordCrudMFADelete(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ExpectedStatus: 403,
|
||||||
|
ExpectedContent: []string{`"data":{}`},
|
||||||
|
ExpectedEvents: map[string]int{"*": 0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "superusers auth",
|
||||||
|
Method: http.MethodDelete,
|
||||||
|
URL: "/api/collections/" + core.CollectionNameMFAs + "/records/user1_0",
|
||||||
|
Headers: map[string]string{
|
||||||
|
// superusers, test@example.com
|
||||||
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
||||||
|
},
|
||||||
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
||||||
|
if err := tests.StubMFARecords(app); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
ExpectedStatus: 204,
|
ExpectedStatus: 204,
|
||||||
ExpectedEvents: map[string]int{
|
ExpectedEvents: map[string]int{
|
||||||
"*": 0,
|
"*": 0,
|
||||||
|
|
|
@ -170,12 +170,12 @@ func TestRecordCrudOTPDelete(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ExpectedStatus: 404,
|
ExpectedStatus: 403,
|
||||||
ExpectedContent: []string{`"data":{}`},
|
ExpectedContent: []string{`"data":{}`},
|
||||||
ExpectedEvents: map[string]int{"*": 0},
|
ExpectedEvents: map[string]int{"*": 0},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "non-owner",
|
Name: "non-owner auth",
|
||||||
Method: http.MethodDelete,
|
Method: http.MethodDelete,
|
||||||
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
||||||
Headers: map[string]string{
|
Headers: map[string]string{
|
||||||
|
@ -187,12 +187,12 @@ func TestRecordCrudOTPDelete(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ExpectedStatus: 404,
|
ExpectedStatus: 403,
|
||||||
ExpectedContent: []string{`"data":{}`},
|
ExpectedContent: []string{`"data":{}`},
|
||||||
ExpectedEvents: map[string]int{"*": 0},
|
ExpectedEvents: map[string]int{"*": 0},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "owner",
|
Name: "owner regular auth",
|
||||||
Method: http.MethodDelete,
|
Method: http.MethodDelete,
|
||||||
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
||||||
Headers: map[string]string{
|
Headers: map[string]string{
|
||||||
|
@ -204,6 +204,23 @@ func TestRecordCrudOTPDelete(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ExpectedStatus: 403,
|
||||||
|
ExpectedContent: []string{`"data":{}`},
|
||||||
|
ExpectedEvents: map[string]int{"*": 0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "superusers auth",
|
||||||
|
Method: http.MethodDelete,
|
||||||
|
URL: "/api/collections/" + core.CollectionNameOTPs + "/records/user1_0",
|
||||||
|
Headers: map[string]string{
|
||||||
|
// superusers, test@example.com
|
||||||
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
||||||
|
},
|
||||||
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
||||||
|
if err := tests.StubOTPRecords(app); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
ExpectedStatus: 204,
|
ExpectedStatus: 204,
|
||||||
ExpectedEvents: map[string]int{
|
ExpectedEvents: map[string]int{
|
||||||
"*": 0,
|
"*": 0,
|
||||||
|
|
|
@ -256,13 +256,13 @@ func EnrichRecords(e *core.RequestEvent, records []*core.Record, defaultExpands
|
||||||
|
|
||||||
return triggerRecordEnrichHooks(e.App, info, records, func() error {
|
return triggerRecordEnrichHooks(e.App, info, records, func() error {
|
||||||
expands := defaultExpands
|
expands := defaultExpands
|
||||||
if param := e.Request.URL.Query().Get(expandQueryParam); param != "" {
|
if param := info.Query[expandQueryParam]; param != "" {
|
||||||
expands = append(expands, strings.Split(param, ",")...)
|
expands = append(expands, strings.Split(param, ",")...)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := defaultEnrichRecords(e.App, info, records, expands...)
|
err := defaultEnrichRecords(e.App, info, records, expands...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// only log as it is not critical
|
// only log because it is not critical
|
||||||
e.App.Logger().Warn("failed to apply default enriching", "error", err)
|
e.App.Logger().Warn("failed to apply default enriching", "error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,8 +270,6 @@ func EnrichRecords(e *core.RequestEvent, records []*core.Record, defaultExpands
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var iterate func(record *core.Record) error
|
|
||||||
|
|
||||||
type iterator[T any] struct {
|
type iterator[T any] struct {
|
||||||
items []T
|
items []T
|
||||||
index int
|
index int
|
||||||
|
@ -297,6 +295,7 @@ func triggerRecordEnrichHooks(app core.App, requestInfo *core.RequestInfo, recor
|
||||||
event.App = app
|
event.App = app
|
||||||
event.RequestInfo = requestInfo
|
event.RequestInfo = requestInfo
|
||||||
|
|
||||||
|
var iterate func(record *core.Record) error
|
||||||
iterate = func(record *core.Record) error {
|
iterate = func(record *core.Record) error {
|
||||||
if record == nil {
|
if record == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -350,6 +349,7 @@ func defaultEnrichRecords(app core.App, requestInfo *core.RequestInfo, records [
|
||||||
|
|
||||||
// expandFetch is the records fetch function that is used to expand related records.
|
// expandFetch is the records fetch function that is used to expand related records.
|
||||||
func expandFetch(app core.App, originalRequestInfo *core.RequestInfo) core.ExpandFetchFunc {
|
func expandFetch(app core.App, originalRequestInfo *core.RequestInfo) core.ExpandFetchFunc {
|
||||||
|
// shallow clone the provided request info to set an "expand" context
|
||||||
requestInfoClone := *originalRequestInfo
|
requestInfoClone := *originalRequestInfo
|
||||||
requestInfoPtr := &requestInfoClone
|
requestInfoPtr := &requestInfoClone
|
||||||
requestInfoPtr.Context = core.RequestInfoContextExpand
|
requestInfoPtr.Context = core.RequestInfoContextExpand
|
||||||
|
|
|
@ -23,6 +23,14 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
app, _ := tests.NewTestApp()
|
app, _ := tests.NewTestApp()
|
||||||
defer app.Cleanup()
|
defer app.Cleanup()
|
||||||
|
|
||||||
|
freshRecords := func(records []*core.Record) []*core.Record {
|
||||||
|
result := make([]*core.Record, len(records))
|
||||||
|
for i, r := range records {
|
||||||
|
result[i] = r.Fresh()
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
user, err := app.FindAuthRecordByEmail("users", "test@example.com")
|
user, err := app.FindAuthRecordByEmail("users", "test@example.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -77,7 +85,7 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "[emailVisibility] guest",
|
name: "[emailVisibility] guest",
|
||||||
auth: nil,
|
auth: nil,
|
||||||
records: usersRecords,
|
records: freshRecords(usersRecords),
|
||||||
queryExpand: "",
|
queryExpand: "",
|
||||||
defaultExpands: nil,
|
defaultExpands: nil,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
|
@ -91,7 +99,7 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "[emailVisibility] owner",
|
name: "[emailVisibility] owner",
|
||||||
auth: user,
|
auth: user,
|
||||||
records: usersRecords,
|
records: freshRecords(usersRecords),
|
||||||
queryExpand: "",
|
queryExpand: "",
|
||||||
defaultExpands: nil,
|
defaultExpands: nil,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
|
@ -103,7 +111,7 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "[emailVisibility] manager",
|
name: "[emailVisibility] manager",
|
||||||
auth: user,
|
auth: user,
|
||||||
records: nologinRecords,
|
records: freshRecords(nologinRecords),
|
||||||
queryExpand: "",
|
queryExpand: "",
|
||||||
defaultExpands: nil,
|
defaultExpands: nil,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
|
@ -115,7 +123,7 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "[emailVisibility] superuser",
|
name: "[emailVisibility] superuser",
|
||||||
auth: superuser,
|
auth: superuser,
|
||||||
records: nologinRecords,
|
records: freshRecords(nologinRecords),
|
||||||
queryExpand: "",
|
queryExpand: "",
|
||||||
defaultExpands: nil,
|
defaultExpands: nil,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
|
@ -127,7 +135,7 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "[emailVisibility + expand] recursive auth rule checks (regular user)",
|
name: "[emailVisibility + expand] recursive auth rule checks (regular user)",
|
||||||
auth: user,
|
auth: user,
|
||||||
records: demo1Records,
|
records: freshRecords(demo1Records),
|
||||||
queryExpand: "",
|
queryExpand: "",
|
||||||
defaultExpands: []string{"rel_many"},
|
defaultExpands: []string{"rel_many"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
|
@ -144,7 +152,7 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "[emailVisibility + expand] recursive auth rule checks (superuser)",
|
name: "[emailVisibility + expand] recursive auth rule checks (superuser)",
|
||||||
auth: superuser,
|
auth: superuser,
|
||||||
records: demo1Records,
|
records: freshRecords(demo1Records),
|
||||||
queryExpand: "",
|
queryExpand: "",
|
||||||
defaultExpands: []string{"rel_many"},
|
defaultExpands: []string{"rel_many"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
|
@ -164,7 +172,7 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "[expand] guest (query)",
|
name: "[expand] guest (query)",
|
||||||
auth: nil,
|
auth: nil,
|
||||||
records: usersRecords,
|
records: freshRecords(usersRecords),
|
||||||
queryExpand: "rel",
|
queryExpand: "rel",
|
||||||
defaultExpands: nil,
|
defaultExpands: nil,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
|
@ -180,7 +188,7 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "[expand] guest (default expands)",
|
name: "[expand] guest (default expands)",
|
||||||
auth: nil,
|
auth: nil,
|
||||||
records: usersRecords,
|
records: freshRecords(usersRecords),
|
||||||
queryExpand: "",
|
queryExpand: "",
|
||||||
defaultExpands: []string{"rel"},
|
defaultExpands: []string{"rel"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
|
@ -193,7 +201,7 @@ func TestEnrichRecords(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "[expand] @request.context=expand check",
|
name: "[expand] @request.context=expand check",
|
||||||
auth: nil,
|
auth: nil,
|
||||||
records: demo5Records,
|
records: freshRecords(demo5Records),
|
||||||
queryExpand: "rel_one",
|
queryExpand: "rel_one",
|
||||||
defaultExpands: []string{"rel_many"},
|
defaultExpands: []string{"rel_many"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
|
|
|
@ -51,6 +51,8 @@ func init() {
|
||||||
[[created]] TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%fZ')) NOT NULL,
|
[[created]] TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%fZ')) NOT NULL,
|
||||||
[[updated]] TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%fZ')) NOT NULL
|
[[updated]] TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%fZ')) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx__collections_type on {{_collections}} ([[type]]);
|
||||||
`).Execute()
|
`).Execute()
|
||||||
if execerr != nil {
|
if execerr != nil {
|
||||||
return fmt.Errorf("_collections exec error: %w", execerr)
|
return fmt.Errorf("_collections exec error: %w", execerr)
|
||||||
|
@ -122,7 +124,6 @@ func createMFAsCollection(txApp core.App) error {
|
||||||
ownerRule := "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId"
|
ownerRule := "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId"
|
||||||
col.ListRule = types.Pointer(ownerRule)
|
col.ListRule = types.Pointer(ownerRule)
|
||||||
col.ViewRule = types.Pointer(ownerRule)
|
col.ViewRule = types.Pointer(ownerRule)
|
||||||
col.DeleteRule = types.Pointer(ownerRule)
|
|
||||||
|
|
||||||
col.Fields.Add(&core.TextField{
|
col.Fields.Add(&core.TextField{
|
||||||
Name: "collectionRef",
|
Name: "collectionRef",
|
||||||
|
@ -162,7 +163,6 @@ func createOTPsCollection(txApp core.App) error {
|
||||||
ownerRule := "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId"
|
ownerRule := "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId"
|
||||||
col.ListRule = types.Pointer(ownerRule)
|
col.ListRule = types.Pointer(ownerRule)
|
||||||
col.ViewRule = types.Pointer(ownerRule)
|
col.ViewRule = types.Pointer(ownerRule)
|
||||||
col.DeleteRule = types.Pointer(ownerRule)
|
|
||||||
|
|
||||||
col.Fields.Add(&core.TextField{
|
col.Fields.Add(&core.TextField{
|
||||||
Name: "collectionRef",
|
Name: "collectionRef",
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
// note: this migration will be deleted in future version
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
core.SystemMigrations.Register(func(txApp core.App) error {
|
||||||
|
_, err := txApp.DB().NewQuery("CREATE INDEX IF NOT EXISTS idx__collections_type on {{_collections}} ([[type]]);").Execute()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset mfas and otps delete rule
|
||||||
|
collectionNames := []string{core.CollectionNameMFAs, core.CollectionNameOTPs}
|
||||||
|
for _, name := range collectionNames {
|
||||||
|
col, err := txApp.FindCollectionByNameOrId(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if col.DeleteRule != nil {
|
||||||
|
col.DeleteRule = nil
|
||||||
|
err = txApp.SaveNoValidate(col)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}, nil)
|
||||||
|
}
|
|
@ -55,6 +55,8 @@ func hooksBinds(app core.App, loader *goja.Runtime, executors *vmsPool) {
|
||||||
|
|
||||||
// register the hook to the loader
|
// register the hook to the loader
|
||||||
loader.Set(jsName, func(callback string, tags ...string) {
|
loader.Set(jsName, func(callback string, tags ...string) {
|
||||||
|
// overwrite the global $app with the hook scoped instance
|
||||||
|
callback = `function(e) { $app = e.app; return (` + callback + `).call(undefined, e) }`
|
||||||
pr := goja.MustCompile("", "{("+callback+").apply(undefined, __args)}", true)
|
pr := goja.MustCompile("", "{("+callback+").apply(undefined, __args)}", true)
|
||||||
|
|
||||||
tagsAsValues := make([]reflect.Value, len(tags))
|
tagsAsValues := make([]reflect.Value, len(tags))
|
||||||
|
@ -74,6 +76,7 @@ func hooksBinds(app core.App, loader *goja.Runtime, executors *vmsPool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
err := executors.run(func(executor *goja.Runtime) error {
|
err := executors.run(func(executor *goja.Runtime) error {
|
||||||
|
executor.Set("$app", goja.Undefined())
|
||||||
executor.Set("__args", handlerArgs)
|
executor.Set("__args", handlerArgs)
|
||||||
res, err := executor.RunProgram(pr)
|
res, err := executor.RunProgram(pr)
|
||||||
executor.Set("__args", goja.Undefined())
|
executor.Set("__args", goja.Undefined())
|
||||||
|
@ -189,6 +192,7 @@ func wrapHandlerFunc(executors *vmsPool, handler goja.Value) (func(*core.Request
|
||||||
|
|
||||||
wrappedHandler := func(e *core.RequestEvent) error {
|
wrappedHandler := func(e *core.RequestEvent) error {
|
||||||
return executors.run(func(executor *goja.Runtime) error {
|
return executors.run(func(executor *goja.Runtime) error {
|
||||||
|
executor.Set("$app", e.App) // overwrite the global $app with the hook scoped instance
|
||||||
executor.Set("__args", []any{e})
|
executor.Set("__args", []any{e})
|
||||||
res, err := executor.RunProgram(pr)
|
res, err := executor.RunProgram(pr)
|
||||||
executor.Set("__args", goja.Undefined())
|
executor.Set("__args", goja.Undefined())
|
||||||
|
@ -245,6 +249,7 @@ func wrapMiddlewares(executors *vmsPool, rawMiddlewares ...goja.Value) ([]*hook.
|
||||||
Priority: v.priority,
|
Priority: v.priority,
|
||||||
Func: func(e *core.RequestEvent) error {
|
Func: func(e *core.RequestEvent) error {
|
||||||
return executors.run(func(executor *goja.Runtime) error {
|
return executors.run(func(executor *goja.Runtime) error {
|
||||||
|
executor.Set("$app", e.App) // overwrite the global $app with the hook scoped instance
|
||||||
executor.Set("__args", []any{e})
|
executor.Set("__args", []any{e})
|
||||||
res, err := executor.RunProgram(pr)
|
res, err := executor.RunProgram(pr)
|
||||||
executor.Set("__args", goja.Undefined())
|
executor.Set("__args", goja.Undefined())
|
||||||
|
@ -266,6 +271,7 @@ func wrapMiddlewares(executors *vmsPool, rawMiddlewares ...goja.Value) ([]*hook.
|
||||||
wrappedMiddlewares[i] = &hook.Handler[*core.RequestEvent]{
|
wrappedMiddlewares[i] = &hook.Handler[*core.RequestEvent]{
|
||||||
Func: func(e *core.RequestEvent) error {
|
Func: func(e *core.RequestEvent) error {
|
||||||
return executors.run(func(executor *goja.Runtime) error {
|
return executors.run(func(executor *goja.Runtime) error {
|
||||||
|
executor.Set("$app", e.App) // overwrite the global $app with the hook scoped instance
|
||||||
executor.Set("__args", []any{e})
|
executor.Set("__args", []any{e})
|
||||||
res, err := executor.RunProgram(pr)
|
res, err := executor.RunProgram(pr)
|
||||||
executor.Set("__args", goja.Undefined())
|
executor.Set("__args", goja.Undefined())
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -217,7 +217,7 @@ declare function sleep(milliseconds: number): void;
|
||||||
* ` + "```" + `js
|
* ` + "```" + `js
|
||||||
* const records = arrayOf(new Record)
|
* const records = arrayOf(new Record)
|
||||||
*
|
*
|
||||||
* $app.dao().recordQuery("articles").limit(10).all(records)
|
* $app.recordQuery("articles").limit(10).all(records)
|
||||||
* ` + "```" + `
|
* ` + "```" + `
|
||||||
*
|
*
|
||||||
* @group PocketBase
|
* @group PocketBase
|
||||||
|
@ -279,7 +279,7 @@ declare class Context implements context.Context {
|
||||||
* Record model class.
|
* Record model class.
|
||||||
*
|
*
|
||||||
* ` + "```" + `js
|
* ` + "```" + `js
|
||||||
* const collection = $app.dao().findCollectionByNameOrId("article")
|
* const collection = $app.findCollectionByNameOrId("article")
|
||||||
*
|
*
|
||||||
* const record = new Record(collection, {
|
* const record = new Record(collection, {
|
||||||
* title: "Lorem ipsum"
|
* title: "Lorem ipsum"
|
||||||
|
|
Binary file not shown.
Binary file not shown.
2
ui/.env
2
ui/.env
|
@ -11,4 +11,4 @@ PB_DOCS_URL = "https://pocketbase.io/docs/"
|
||||||
PB_JS_SDK_URL = "https://github.com/pocketbase/js-sdk"
|
PB_JS_SDK_URL = "https://github.com/pocketbase/js-sdk"
|
||||||
PB_DART_SDK_URL = "https://github.com/pocketbase/dart-sdk"
|
PB_DART_SDK_URL = "https://github.com/pocketbase/dart-sdk"
|
||||||
PB_RELEASES = "https://github.com/pocketbase/pocketbase/releases"
|
PB_RELEASES = "https://github.com/pocketbase/pocketbase/releases"
|
||||||
PB_VERSION = "v0.23.0-rc7"
|
PB_VERSION = "v0.23.0-rc8"
|
||||||
|
|
Loading…
Reference in New Issue