@@ -261,6 +261,16 @@ HiveMind::HiveMind(Config conf_in) :
261
261
.add_request_command (
262
262
" get_stats" , ExcWrapper{*this , &HiveMind::on_get_stats, " on_get_stats" })
263
263
264
+ // Drops one or more registrations; this is invoked by a notifier when the upstream
265
+ // notification service has indicated that the notification token is no longer valid.
266
+ //
267
+ // Called with two values: the service id (e.g. "apns", "firebase") and a bt-encoded
268
+ // list of unique service ids (as would have been returned by the service's
269
+ // notifier.validate) to remote. This endpoint is a command (i.e. has no reply).
270
+ .add_command (
271
+ " drop_registrations" ,
272
+ ExcWrapper{*this , &HiveMind::on_drop_registrations, " on_drop_registrations" })
273
+
264
274
// end of "admin." commands
265
275
;
266
276
@@ -924,6 +934,55 @@ void HiveMind::log_stats(std::string_view pre_cmd) {
924
934
}
925
935
}
926
936
937
+ void HiveMind::on_drop_registrations (oxenmq::Message& m) {
938
+ if (m.data .size () != 2 ) {
939
+ log::warning (cat, " Invalid admin.drop_registrations call: expected 2-part message" );
940
+ return ;
941
+ }
942
+
943
+ auto service = m.data [0 ];
944
+ if (service.empty ()) {
945
+ log::warning (cat, " admin.drop_registrations received illegal empty service name" );
946
+ return ;
947
+ }
948
+
949
+ oxenc::bt_list_consumer drops{m.data [1 ]};
950
+ if (drops.is_finished ()) {
951
+ log::warning (cat, " admin.drop_registrations called with empty token list" );
952
+ return ;
953
+ }
954
+ auto conn = pool_.get ();
955
+ int reqed = 0 , deleted = 0 , matched = 0 ;
956
+ try {
957
+ pqxx::work tx{conn};
958
+ while (!drops.is_finished ()) {
959
+ reqed++;
960
+ auto del = tx.exec_params0 (
961
+ " DELETE FROM subscriptions WHERE service = $1 AND svcid = $2" ,
962
+ service,
963
+ drops.consume_string_view ())
964
+ .affected_rows ();
965
+ deleted += del;
966
+ if (del)
967
+ matched++;
968
+ }
969
+ tx.commit ();
970
+ } catch (const oxenc::bt_deserialize_invalid_type&) {
971
+ log::warning (
972
+ cat,
973
+ " invalid admin.on_drop_registration request: expected list of service id strings" );
974
+ return ;
975
+ }
976
+
977
+ log::info (
978
+ cat,
979
+ " Dropped {} (of {} requested) {} service IDs, totalling {} account subscriptions" ,
980
+ matched,
981
+ reqed,
982
+ service,
983
+ deleted);
984
+ }
985
+
927
986
static void sub_json_set_one_response (
928
987
oxenmq::Message::DeferredSend&& m,
929
988
nlohmann::json& response,
0 commit comments