Hello from MCP server
package main
import (
"encoding/json"
"strings"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/types"
)
func registerHookPreApprovedEmails(app *pocketbase.PocketBase) {
app.OnRecordAfterCreateSuccess("users").BindFunc(func(e *core.RecordEvent) error {
userEmail := strings.ToLower(e.Record.GetString("email"))
userId := e.Record.Id
// Find all organizations
orgs, err := app.FindAllRecords("organizations")
if err != nil {
app.Logger().Error("Failed to fetch organizations for pre-approved email check", "error", err)
return e.Next()
}
var firstMatchingOrgId string
profilesCollection, err := app.FindCollectionByNameOrId("profiles")
if err != nil {
app.Logger().Error("Failed to find profiles collection", "error", err)
return e.Next()
}
for _, org := range orgs {
orgId := org.Id
variablesRaw := org.Get("variables")
if variablesRaw == nil {
continue
}
// Parse variables - handle both string and types.JSONRaw
var variablesBytes []byte
switch v := variablesRaw.(type) {
case string:
variablesBytes = []byte(v)
case types.JSONRaw:
variablesBytes = []byte(v)
default:
continue
}
var variables map[string]interface{}
if err := json.Unmarshal(variablesBytes, &variables); err != nil {
continue
}
// Check for preApprovedEmails array
preApprovedRaw, exists := variables["preApprovedEmails"]
if !exists {
continue
}
preApprovedList, ok := preApprovedRaw.([]interface{})
if !ok {
continue
}
// Check if user's email is in the pre-approved list (case-insensitive)
matchIndex := -1
for i, emailRaw := range preApprovedList {
email, ok := emailRaw.(string)
if !ok {
continue
}
if strings.ToLower(email) == userEmail {
matchIndex = i
break
}
}
if matchIndex == -1 {
continue
}
// Found a match - find the "tech" role for this org
techRole, err := app.FindFirstRecordByFilter(
"roles",
"org = {:org} && name = {:name}",
dbx.Params{"org": orgId, "name": "tech"},
)
if err != nil {
app.Logger().Error("Failed to find tech role for org", "orgId", orgId, "error", err)
continue
}
// Create a profile linking user to org with tech role
profile := core.NewRecord(profilesCollection)
profile.Set("org", orgId)
profile.Set("user", userId)
profile.Set("roles", []string{techRole.Id})
if err := app.Save(profile); err != nil {
app.Logger().Error("Failed to create profile for pre-approved user", "userId", userId, "orgId", orgId, "error", err)
continue
}
// Track first matching org for activeOrg
if firstMatchingOrgId == "" {
firstMatchingOrgId = orgId
}
// Remove email from preApprovedEmails list
newPreApprovedList := append(preApprovedList[:matchIndex], preApprovedList[matchIndex+1:]...)
variables["preApprovedEmails"] = newPreApprovedList
// Save updated variables back to org
updatedVariablesJson, err := json.Marshal(variables)
if err != nil {
app.Logger().Error("Failed to marshal updated variables", "orgId", orgId, "error", err)
continue
}
org.Set("variables", string(updatedVariablesJson))
if err := app.Save(org); err != nil {
app.Logger().Error("Failed to save org with updated preApprovedEmails", "orgId", orgId, "error", err)
continue
}
app.Logger().Info("Auto-enrolled pre-approved user", "userId", userId, "email", userEmail, "orgId", orgId)
}
// Set user's activeOrg to first matching org
if firstMatchingOrgId != "" {
user, err := app.FindRecordById("users", userId)
if err != nil {
app.Logger().Error("Failed to find user to set activeOrg", "userId", userId, "error", err)
return e.Next()
}
user.Set("activeOrg", firstMatchingOrgId)
if err := app.Save(user); err != nil {
app.Logger().Error("Failed to set activeOrg for user", "userId", userId, "error", err)
}
}
return e.Next()
})
}