MCPcopy
hub / github.com/pocketbase/pocketbase / realtimeSetSubscriptions

Function realtimeSetSubscriptions

apis/realtime.go:184–249  ·  view source on GitHub ↗

note: in case of reconnect, clients will have to resubmit all subscriptions again

(e *core.RequestEvent)

Source from the content-addressed store, hash-verified

182
183// note: in case of reconnect, clients will have to resubmit all subscriptions again
184func realtimeSetSubscriptions(e *core.RequestEvent) error {
185 form := new(realtimeSubscribeForm)
186
187 err := e.BindBody(form)
188 if err != nil {
189 return e.BadRequestError("", err)
190 }
191
192 err = form.validate()
193 if err != nil {
194 return e.BadRequestError("", err)
195 }
196
197 // find subscription client
198 client, err := e.App.SubscriptionsBroker().ClientById(form.ClientId)
199 if err != nil {
200 return e.NotFoundError("Missing or invalid client id.", err)
201 }
202
203 // for just in case to prevent someone changing a guest subscription
204 //
205 // note1: this is an extra precaution against clientId bruteforce attempts
206 // for installations allowing longer realtime connections duration
207 //
208 // note2: custom registered clients (aka. those without IP in the store)
209 // are excluded from the check for backward compatibility
210 clientIP, _ := client.Get(RealtimeClientIPKey).(string)
211 if clientIP != "" && clientIP != e.RealIP() {
212 return e.BadRequestError(
213 "Invalid realtime client.",
214 errors.New("the subscription request IP doesn't match with the realtime client IP"),
215 )
216 }
217
218 // for now allow only guest->auth upgrades and any other auth change is forbidden
219 clientAuth, _ := client.Get(RealtimeClientAuthKey).(*core.Record)
220 if clientAuth != nil && !isSameAuth(clientAuth, e.Auth) {
221 return e.ForbiddenError("The current and the previous request authorization don't match.", nil)
222 }
223
224 event := new(core.RealtimeSubscribeRequestEvent)
225 event.RequestEvent = e
226 event.Client = client
227 event.Subscriptions = form.Subscriptions
228
229 return e.App.OnRealtimeSubscribeRequest().Trigger(event, func(e *core.RealtimeSubscribeRequestEvent) error {
230 // update auth state
231 e.Client.Set(RealtimeClientAuthKey, e.Auth)
232
233 // unsubscribe from any previous existing subscriptions
234 e.Client.Unsubscribe()
235
236 // subscribe to the new subscriptions
237 e.Client.Subscribe(e.Subscriptions...)
238
239 e.App.Logger().Debug(
240 "Realtime subscriptions updated",
241 slog.String("clientId", e.Client.Id()),

Callers

nothing calls this directly

Calls 15

isSameAuthFunction · 0.85
execAfterSuccessTxFunction · 0.85
BindBodyMethod · 0.80
BadRequestErrorMethod · 0.80
ClientByIdMethod · 0.80
NotFoundErrorMethod · 0.80
RealIPMethod · 0.80
ForbiddenErrorMethod · 0.80
TriggerMethod · 0.80
AnyMethod · 0.80
NoContentMethod · 0.80
validateMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…