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
This commit is contained in:
congsh
2026-04-17 14:17:54 +08:00
parent 8d4b9a167c
commit 2db391901c
+61 -46
View File
@@ -2,12 +2,10 @@ package main
import ( import (
"log" "log"
"strings"
"github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core" "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 // isGroupMember checks if a user is a member of a group
@@ -39,70 +37,90 @@ func main() {
app := pocketbase.New() app := pocketbase.New()
// Groups API Rules // 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 // 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 // Initialize members array with the owner
e.Record.Set("members", []string{e.Record.GetString("owner")}) e.Record.Set("members", []string{authRecord.Id})
return next
return nil
}) })
app.OnRecordBeforeUpdateRequest("groups").Add(func(e *core.RecordUpdateEvent) next func() { app.OnRecordBeforeUpdateRequest("groups").Add(func(e *core.RecordUpdateEvent) error {
userId := e.HttpContext.Request().Context().Value("user_id").(string) authRecord, _ := e.HttpContext.AuthRecord()
if authRecord == nil {
return apis.NewForbiddenError("需要登录", nil)
}
// Only owner can update the group // 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 { if err != nil || !isOwner {
e.HttpContext.Response().WriteHeader(403) return apis.NewForbiddenError("只有群组所有者可以更新群组", nil)
return nil
} }
return next
return nil
}) })
app.OnRecordBeforeDeleteRequest("groups").Add(func(e *core.RecordDeleteEvent) next func() { app.OnRecordBeforeDeleteRequest("groups").Add(func(e *core.RecordDeleteEvent) error {
userId := e.HttpContext.Request().Context().Value("user_id").(string) authRecord, _ := e.HttpContext.AuthRecord()
if authRecord == nil {
return apis.NewForbiddenError("需要登录", nil)
}
// Only owner can delete the group // 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 { if err != nil || !isOwner {
e.HttpContext.Response().WriteHeader(403) return apis.NewForbiddenError("只有群组所有者可以删除群组", nil)
return nil
} }
return next
return nil
}) })
// Team Sessions API Rules // Team Sessions API Rules
app.OnRecordBeforeCreateRequest("team_sessions").Add(func(e *core.RecordCreateEvent) next func() { app.OnRecordBeforeCreateRequest("team_sessions").Add(func(e *core.RecordCreateEvent) error {
userId := e.HttpContext.Request().Context().Value("user_id").(string) authRecord, _ := e.HttpContext.AuthRecord()
if authRecord == nil {
return apis.NewForbiddenError("需要登录", nil)
}
groupId := e.Record.GetString("group") groupId := e.Record.GetString("group")
// Check if user is a member of the 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 { if err != nil || !isMember {
e.HttpContext.Response().WriteHeader(403) return apis.NewForbiddenError("只有群组成员可以创建团队会话", nil)
return nil
} }
return next
return nil
}) })
// Invitations API Rules // Invitations API Rules
app.OnRecordBeforeCreateRequest("invitations").Add(func(e *core.RecordCreateEvent) next func() { app.OnRecordBeforeCreateRequest("invitations").Add(func(e *core.RecordCreateEvent) error {
userId := e.HttpContext.Request().Context().Value("user_id").(string) authRecord, _ := e.HttpContext.AuthRecord()
if authRecord == nil {
return apis.NewForbiddenError("需要登录", nil)
}
groupId := e.Record.GetString("group") groupId := e.Record.GetString("group")
// Only group owner can create invitations // Only group owner can create invitations
isOwner, err := isGroupOwner(app, groupId, userId) isOwner, err := isGroupOwner(app, groupId, authRecord.Id)
if err != nil || !isOwner { if err != nil || !isOwner {
e.HttpContext.Response().WriteHeader(403) return apis.NewForbiddenError("只有群组所有者可以创建邀请", nil)
return nil
} }
// Set status to pending // Set status to pending
e.Record.Set("status", "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 // Send real-time notification to the invited user
message := map[string]interface{}{ message := map[string]interface{}{
"action": "invitation", "action": "invitation",
@@ -116,29 +134,26 @@ func main() {
} }
// Broadcast to the invited user's channel // 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) log.Printf("Error broadcasting invitation: %v", err)
} }
return next
return nil
}) })
// Real-time subscription rules // Real-time subscription rules
app.OnRecordAfterAuthWithTokenRequest().Add(func(e *core.RecordAuthEvent) next func() { app.OnRecordAfterAuthWithTokenRequest().Add(func(e *core.RecordAuthEvent) error {
// Subscribe to invitations channel // Subscribe to invitations channel and user's groups channel
e.HttpContext.Request().Context().Set("realtime_subscriptions", []string{ app.Subscriptions().Subscribe(e.HttpContext.Response(), []string{
"invitations", "invitations",
"groups:" + e.Record.Id, "groups:" + e.Record.Id,
"team_sessions", "team_sessions",
}) })
return next
return nil
}) })
// Custom API endpoint for accepting invitations if err := app.Start(); err != nil {
app.OnServe().Bind(&ServeEvent{ log.Fatal(err)
App: app, }
})
}
type ServeEvent struct {
App *pocketbase.PocketBase
} }