You've already forked pocketbase
							
							
				mirror of
				https://github.com/pocketbase/pocketbase.git
				synced 2025-10-31 16:47:43 +02:00 
			
		
		
		
	[#5898] instead of unregister, unset the realtime client auth state on delete of the related auth record
This commit is contained in:
		| @@ -2,6 +2,11 @@ | ||||
| > For the most recent versions, please refer to [CHANGELOG.md](./CHANGELOG.md) | ||||
| --- | ||||
|  | ||||
| ## v0.22.27 | ||||
|  | ||||
| - Instead of unregistering the realtime clients, we now just unset their auth state on delete of the related auth record so that the clients can receive the `delete` event ([#5898](https://github.com/pocketbase/pocketbase/issues/5898)). | ||||
|  | ||||
|  | ||||
| ## v0.22.26 | ||||
|  | ||||
| - (_Backported from v0.23.0-rc_) Added manual WAL checkpoints before creating the zip backup to minimize copying unnecessary data. | ||||
|   | ||||
| @@ -242,8 +242,8 @@ func realtimeUpdateClientsAuth(app core.App, newAuthRecord *core.Record) error { | ||||
| 	return group.Wait() | ||||
| } | ||||
|  | ||||
| // unregisterClientsByAuthModel unregister all clients that has the provided auth model. | ||||
| func realtimeUnregisterClientsByAuth(app core.App, authModel core.Model) error { | ||||
| // realtimeUnsetClientsAuthState unsets the auth state of all clients that have the provided auth model. | ||||
| func realtimeUnsetClientsAuthState(app core.App, authModel core.Model) error { | ||||
| 	chunks := app.SubscriptionsBroker().ChunkedClients(clientsChunkSize) | ||||
|  | ||||
| 	group := new(errgroup.Group) | ||||
| @@ -255,7 +255,7 @@ func realtimeUnregisterClientsByAuth(app core.App, authModel core.Model) error { | ||||
| 				if clientAuth != nil && | ||||
| 					clientAuth.Id == authModel.PK() && | ||||
| 					clientAuth.Collection().Name == authModel.TableName() { | ||||
| 					app.SubscriptionsBroker().Unregister(client.Id()) | ||||
| 					client.Unset(RealtimeClientAuthKey) | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @@ -293,7 +293,7 @@ func bindRealtimeEvents(app core.App) { | ||||
| 		Func: func(e *core.ModelEvent) error { | ||||
| 			collection := realtimeResolveRecordCollection(e.App, e.Model) | ||||
| 			if collection != nil && collection.IsAuth() { | ||||
| 				if err := realtimeUnregisterClientsByAuth(e.App, e.Model); err != nil { | ||||
| 				if err := realtimeUnsetClientsAuthState(e.App, e.Model); err != nil { | ||||
| 					app.Logger().Warn( | ||||
| 						"Failed to remove client(s) associated to the deleted auth model", | ||||
| 						slog.Any("id", e.Model.PK()), | ||||
|   | ||||
| @@ -427,26 +427,51 @@ func TestRealtimeAuthRecordDeleteEvent(t *testing.T) { | ||||
| 	// init realtime handlers | ||||
| 	apis.NewRouter(testApp) | ||||
|  | ||||
| 	authRecord, err := testApp.FindAuthRecordByEmail("users", "test@example.com") | ||||
| 	authRecord1, err := testApp.FindFirstRecordByData("users", "email", "test@example.com") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	client := subscriptions.NewDefaultClient() | ||||
| 	client.Set(apis.RealtimeClientAuthKey, authRecord) | ||||
| 	testApp.SubscriptionsBroker().Register(client) | ||||
| 	authRecord2, err := testApp.FindFirstRecordByData("users", "email", "test2@example.com") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	client1 := subscriptions.NewDefaultClient() | ||||
| 	client1.Set(apis.RealtimeClientAuthKey, authRecord1) | ||||
| 	testApp.SubscriptionsBroker().Register(client1) | ||||
|  | ||||
| 	client2 := subscriptions.NewDefaultClient() | ||||
| 	client2.Set(apis.RealtimeClientAuthKey, authRecord1) | ||||
| 	testApp.SubscriptionsBroker().Register(client2) | ||||
|  | ||||
| 	client3 := subscriptions.NewDefaultClient() | ||||
| 	client3.Set(apis.RealtimeClientAuthKey, authRecord2) | ||||
| 	testApp.SubscriptionsBroker().Register(client3) | ||||
|  | ||||
| 	// mock delete event | ||||
| 	e := new(core.ModelEvent) | ||||
| 	e.App = testApp | ||||
| 	e.Type = core.ModelEventTypeDelete | ||||
| 	e.Context = context.Background() | ||||
| 	e.Model = authRecord | ||||
| 	e.Model = authRecord1 | ||||
|  | ||||
| 	testApp.OnModelAfterDeleteSuccess().Trigger(e) | ||||
|  | ||||
| 	if total := len(testApp.SubscriptionsBroker().Clients()); total != 0 { | ||||
| 		t.Fatalf("Expected no subscription clients, found %d", total) | ||||
| 	if total := len(testApp.SubscriptionsBroker().Clients()); total != 3 { | ||||
| 		t.Fatalf("Expected %d subscription clients, found %d", 3, total) | ||||
| 	} | ||||
|  | ||||
| 	if auth := client1.Get(apis.RealtimeClientAuthKey); auth != nil { | ||||
| 		t.Fatalf("[client1] Expected the auth state to be unset, found %#v", auth) | ||||
| 	} | ||||
|  | ||||
| 	if auth := client2.Get(apis.RealtimeClientAuthKey); auth != nil { | ||||
| 		t.Fatalf("[client2] Expected the auth state to be unset, found %#v", auth) | ||||
| 	} | ||||
|  | ||||
| 	if auth := client3.Get(apis.RealtimeClientAuthKey); auth == nil || auth.(*core.Record).Id != authRecord2.Id { | ||||
| 		t.Fatalf("[client3] Expected the auth state to be left unchanged, found %#v", auth) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -524,17 +549,30 @@ func TestRealtimeCustomAuthModelDeleteEvent(t *testing.T) { | ||||
| 	// init realtime handlers | ||||
| 	apis.NewRouter(testApp) | ||||
|  | ||||
| 	authRecord, err := testApp.FindAuthRecordByEmail("users", "test@example.com") | ||||
| 	authRecord1, err := testApp.FindFirstRecordByData("users", "email", "test@example.com") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	client := subscriptions.NewDefaultClient() | ||||
| 	client.Set(apis.RealtimeClientAuthKey, authRecord) | ||||
| 	testApp.SubscriptionsBroker().Register(client) | ||||
| 	authRecord2, err := testApp.FindFirstRecordByData("users", "email", "test2@example.com") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	client1 := subscriptions.NewDefaultClient() | ||||
| 	client1.Set(apis.RealtimeClientAuthKey, authRecord1) | ||||
| 	testApp.SubscriptionsBroker().Register(client1) | ||||
|  | ||||
| 	client2 := subscriptions.NewDefaultClient() | ||||
| 	client2.Set(apis.RealtimeClientAuthKey, authRecord1) | ||||
| 	testApp.SubscriptionsBroker().Register(client2) | ||||
|  | ||||
| 	client3 := subscriptions.NewDefaultClient() | ||||
| 	client3.Set(apis.RealtimeClientAuthKey, authRecord2) | ||||
| 	testApp.SubscriptionsBroker().Register(client3) | ||||
|  | ||||
| 	// refetch the authRecord as CustomUser | ||||
| 	customUser, err := findCustomUserByEmail(testApp, "test@example.com") | ||||
| 	customUser, err := findCustomUserByEmail(testApp, authRecord1.Email()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -544,8 +582,20 @@ func TestRealtimeCustomAuthModelDeleteEvent(t *testing.T) { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if total := len(testApp.SubscriptionsBroker().Clients()); total != 0 { | ||||
| 		t.Fatalf("Expected no subscription clients, found %d", total) | ||||
| 	if total := len(testApp.SubscriptionsBroker().Clients()); total != 3 { | ||||
| 		t.Fatalf("Expected %d subscription clients, found %d", 3, total) | ||||
| 	} | ||||
|  | ||||
| 	if auth := client1.Get(apis.RealtimeClientAuthKey); auth != nil { | ||||
| 		t.Fatalf("[client1] Expected the auth state to be unset, found %#v", auth) | ||||
| 	} | ||||
|  | ||||
| 	if auth := client2.Get(apis.RealtimeClientAuthKey); auth != nil { | ||||
| 		t.Fatalf("[client2] Expected the auth state to be unset, found %#v", auth) | ||||
| 	} | ||||
|  | ||||
| 	if auth := client3.Get(apis.RealtimeClientAuthKey); auth == nil || auth.(*core.Record).Id != authRecord2.Id { | ||||
| 		t.Fatalf("[client3] Expected the auth state to be left unchanged, found %#v", auth) | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user