diff --git a/include/ircd/m/user/keys.h b/include/ircd/m/user/keys.h index e5d42d475..c04ccba2b 100644 --- a/include/ircd/m/user/keys.h +++ b/include/ircd/m/user/keys.h @@ -38,6 +38,7 @@ struct ircd::m::user::keys void cross_self(json::stack::object &) const; void cross_user(json::stack::object &) const; + bool claim(json::stack::object &, const string_view &device_id, const string_view &algo) const; void update(const m::signing_key_update &) const; keys(const m::user &user) diff --git a/matrix/user_keys.cc b/matrix/user_keys.cc index cdaa505e5..1121c8ad7 100644 --- a/matrix/user_keys.cc +++ b/matrix/user_keys.cc @@ -138,6 +138,78 @@ const }; } +bool +ircd::m::user::keys::claim(json::stack::object &object, + const string_view &device_id, + const string_view &algorithm) +const +{ + const fmt::bsprintf type + { + "ircd.device.one_time_key|%s", + algorithm + }; + + const m::room::type events + { + user_room, type, { -1UL, -1L }, true + }; + + return !events.for_each([this, &object, &device_id] + (const string_view &type, const auto &, const m::event::idx &event_idx) + { + if(m::redacted(event_idx)) + return true; + + const bool match + { + m::query(std::nothrow, event_idx, "state_key", [&device_id] + (const string_view &state_key) noexcept + { + return state_key == device_id; + }) + }; + + if(!match) + return true; + + const auto algorithm + { + split(type, '|').second + }; + + const bool fetched + { + m::get(std::nothrow, event_idx, "content", [&object, &algorithm] + (const json::object &content) + { + json::stack::member + { + object, algorithm, json::object + { + content[""] // ircd.device.* quirk + } + }; + }) + }; + + if(!fetched) + return true; + + const auto event_id + { + m::event_id(event_idx) + }; + + const auto redact_id + { + m::redact(user_room, user_room.user, event_id, "claimed") + }; + + return false; + }); +} + void ircd::m::user::keys::device(json::stack::object &out, const string_view &device_id) diff --git a/modules/federation/user_keys_claim.cc b/modules/federation/user_keys_claim.cc index aa3e6e064..412a1fcb8 100644 --- a/modules/federation/user_keys_claim.cc +++ b/modules/federation/user_keys_claim.cc @@ -67,7 +67,7 @@ post__user_keys_claim(client &client, if(!m::exists(user_id)) continue; - const m::user::room user_room + const m::user::keys keys { user_id }; @@ -77,19 +77,11 @@ post__user_keys_claim(client &client, response_keys, user_id }; - for(const auto &[device_id_, algorithm_] : json::object(devices)) + for(const auto &[device_id, algorithm_] : json::object(devices)) { - const auto &device_id{device_id_}; - const json::string &algorithm{algorithm_}; - const fmt::bsprintf type + const json::string algorithm { - "ircd.device.one_time_key|%s", - algorithm - }; - - const m::room::type events - { - user_room, type, { -1UL, -1L }, true + algorithm_ }; json::stack::object response_device @@ -97,54 +89,7 @@ post__user_keys_claim(client &client, response_user, device_id }; - events.for_each([&user_room, &response_device, &device_id, &algorithm] - (const string_view &type, const auto &, const m::event::idx &event_idx) - { - if(m::redacted(event_idx)) - return true; - - const bool match - { - m::query(std::nothrow, event_idx, "state_key", [&device_id] - (const string_view &state_key) noexcept - { - return state_key == device_id; - }) - }; - - if(!match) - return true; - - const bool fetched - { - m::get(std::nothrow, event_idx, "content", [&response_device, &algorithm] - (const json::object &content) - { - json::stack::member - { - response_device, algorithm, json::object - { - content[""] // ircd.device.* quirk - } - }; - }) - }; - - if(!fetched) - return true; - - const auto event_id - { - m::event_id(event_idx) - }; - - const auto redact_id - { - m::redact(user_room, user_room.user, event_id, "claimed") - }; - - return false; - }); + keys.claim(response_device, device_id, algorithm); } }