diff --git a/modules/client/sync/device_one_time_keys_count.cc b/modules/client/sync/device_one_time_keys_count.cc index 10251fa43..4ea65b597 100644 --- a/modules/client/sync/device_one_time_keys_count.cc +++ b/modules/client/sync/device_one_time_keys_count.cc @@ -33,11 +33,59 @@ ircd::m::sync::device_one_time_keys_count bool ircd::m::sync::device_one_time_keys_count_linear(data &data) { - return false; + if(!data.device_id) + return false; + + return device_one_time_keys_count_polylog(data); } bool ircd::m::sync::device_one_time_keys_count_polylog(data &data) { - return false; + if(!data.device_id) + return false; + + const auto event_idx + { + data.user_room.get(std::nothrow, "ircd.device_one_time_keys", data.device_id) + }; + + if(!apropos(data, event_idx)) + return false; + + std::map> counts; + m::device::get(data.user, data.device_id, "one_time_keys", [&counts] + (const string_view &one_time_keys) + { + if(json::type(one_time_keys) != json::OBJECT) + return; + + for(const auto &[ident_, object] : json::object(one_time_keys)) + { + const auto &[algorithm, ident] + { + split(ident_, ':') + }; + + auto it(counts.lower_bound(algorithm)); + if(it == end(counts) || it->first != algorithm) + it = counts.emplace_hint(it, algorithm, 0L); + + auto &count(it->second); + ++count; + } + }); + + json::stack::object one_time_keys_count + { + *data.out, "device_one_time_keys_count" + }; + + for(const auto &[algorithm, count] : counts) + json::stack::member + { + one_time_keys_count, algorithm, json::value{count} + }; + + return true; }