From 2db391901c143cf541aaf61fb224ba17066c7763 Mon Sep 17 00:00:00 2001 From: congsh Date: Fri, 17 Apr 2026 14:17:54 +0800 Subject: [PATCH] fix: use proper PocketBase hook patterns - Replace unsafe type assertions with safe AuthRecord() method - Remove unused 'strings' import - Remove unused ServeEvent struct and binding - Use proper error response methods (apis.NewForbiddenError) - Use app.Subscriptions().Broadcast() instead of Realtime() - Fix hook signatures to return error instead of next function --- backend/pb_hooks/main.go | 107 ++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 46 deletions(-) diff --git a/backend/pb_hooks/main.go b/backend/pb_hooks/main.go index 4237a97..a7a7e1e 100644 --- a/backend/pb_hooks/main.go +++ b/backend/pb_hooks/main.go @@ -2,12 +2,10 @@ package main import ( "log" - "strings" "github.com/pocketbase/pocketbase" + "github.com/pocketbase/pocketbase/apis" "github.com/pocketbase/pocketbase/core" - "github.com/pocketbase/pocketbase/models" - "github.com/pocketbase/pocketbase/tools/types" ) // isGroupMember checks if a user is a member of a group @@ -39,70 +37,90 @@ func main() { app := pocketbase.New() // Groups API Rules - app.OnRecordBeforeCreateRequest("groups").Add(func(e *core.RecordCreateEvent) next func() { + app.OnRecordBeforeCreateRequest("groups").Add(func(e *core.RecordCreateEvent) error { + authRecord, _ := e.HttpContext.AuthRecord() + if authRecord == nil { + return apis.NewForbiddenError("需要登录", nil) + } + // Set the owner to the current user - e.Record.Set("owner", e.HttpContext.Request().Context().Value("user_id")) + e.Record.Set("owner", authRecord.Id) // Initialize members array with the owner - e.Record.Set("members", []string{e.Record.GetString("owner")}) - return next + e.Record.Set("members", []string{authRecord.Id}) + + return nil }) - app.OnRecordBeforeUpdateRequest("groups").Add(func(e *core.RecordUpdateEvent) next func() { - userId := e.HttpContext.Request().Context().Value("user_id").(string) + app.OnRecordBeforeUpdateRequest("groups").Add(func(e *core.RecordUpdateEvent) error { + authRecord, _ := e.HttpContext.AuthRecord() + if authRecord == nil { + return apis.NewForbiddenError("需要登录", nil) + } // Only owner can update the group - isOwner, err := isGroupOwner(app, e.Record.Id, userId) + isOwner, err := isGroupOwner(app, e.Record.Id, authRecord.Id) if err != nil || !isOwner { - e.HttpContext.Response().WriteHeader(403) - return nil + return apis.NewForbiddenError("只有群组所有者可以更新群组", nil) } - return next + + return nil }) - app.OnRecordBeforeDeleteRequest("groups").Add(func(e *core.RecordDeleteEvent) next func() { - userId := e.HttpContext.Request().Context().Value("user_id").(string) + app.OnRecordBeforeDeleteRequest("groups").Add(func(e *core.RecordDeleteEvent) error { + authRecord, _ := e.HttpContext.AuthRecord() + if authRecord == nil { + return apis.NewForbiddenError("需要登录", nil) + } // Only owner can delete the group - isOwner, err := isGroupOwner(app, e.Record.Id, userId) + isOwner, err := isGroupOwner(app, e.Record.Id, authRecord.Id) if err != nil || !isOwner { - e.HttpContext.Response().WriteHeader(403) - return nil + return apis.NewForbiddenError("只有群组所有者可以删除群组", nil) } - return next + + return nil }) // Team Sessions API Rules - app.OnRecordBeforeCreateRequest("team_sessions").Add(func(e *core.RecordCreateEvent) next func() { - userId := e.HttpContext.Request().Context().Value("user_id").(string) + app.OnRecordBeforeCreateRequest("team_sessions").Add(func(e *core.RecordCreateEvent) error { + authRecord, _ := e.HttpContext.AuthRecord() + if authRecord == nil { + return apis.NewForbiddenError("需要登录", nil) + } + groupId := e.Record.GetString("group") // Check if user is a member of the group - isMember, err := isGroupMember(app, groupId, userId) + isMember, err := isGroupMember(app, groupId, authRecord.Id) if err != nil || !isMember { - e.HttpContext.Response().WriteHeader(403) - return nil + return apis.NewForbiddenError("只有群组成员可以创建团队会话", nil) } - return next + + return nil }) // Invitations API Rules - app.OnRecordBeforeCreateRequest("invitations").Add(func(e *core.RecordCreateEvent) next func() { - userId := e.HttpContext.Request().Context().Value("user_id").(string) + app.OnRecordBeforeCreateRequest("invitations").Add(func(e *core.RecordCreateEvent) error { + authRecord, _ := e.HttpContext.AuthRecord() + if authRecord == nil { + return apis.NewForbiddenError("需要登录", nil) + } + groupId := e.Record.GetString("group") // Only group owner can create invitations - isOwner, err := isGroupOwner(app, groupId, userId) + isOwner, err := isGroupOwner(app, groupId, authRecord.Id) if err != nil || !isOwner { - e.HttpContext.Response().WriteHeader(403) - return nil + return apis.NewForbiddenError("只有群组所有者可以创建邀请", nil) } // Set status to pending e.Record.Set("status", "pending") - return next + + return nil }) - app.OnRecordAfterCreateRequest("invitations").Add(func(e *core.RecordCreateEvent) next func() { + app.OnRecordAfterCreateRequest("invitations").Add(func(e *core.RecordCreateEvent) error { // Send real-time notification to the invited user message := map[string]interface{}{ "action": "invitation", @@ -116,29 +134,26 @@ func main() { } // Broadcast to the invited user's channel - if err := app.Realtime().Broadcast("invitations", message); err != nil { + if err := app.Subscriptions().Broadcast("invitations", message); err != nil { log.Printf("Error broadcasting invitation: %v", err) } - return next + + return nil }) // Real-time subscription rules - app.OnRecordAfterAuthWithTokenRequest().Add(func(e *core.RecordAuthEvent) next func() { - // Subscribe to invitations channel - e.HttpContext.Request().Context().Set("realtime_subscriptions", []string{ + app.OnRecordAfterAuthWithTokenRequest().Add(func(e *core.RecordAuthEvent) error { + // Subscribe to invitations channel and user's groups channel + app.Subscriptions().Subscribe(e.HttpContext.Response(), []string{ "invitations", "groups:" + e.Record.Id, "team_sessions", }) - return next + + return nil }) - // Custom API endpoint for accepting invitations - app.OnServe().Bind(&ServeEvent{ - App: app, - }) -} - -type ServeEvent struct { - App *pocketbase.PocketBase + if err := app.Start(); err != nil { + log.Fatal(err) + } }