0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-05-20 03:43:47 +02:00

ircd:Ⓜ️:device: Reclassify interface at m::user::devices.

This commit is contained in:
Jason Volk 2020-04-01 18:30:02 -07:00
parent 6c0e6d49fb
commit fe9635a70e
17 changed files with 422 additions and 278 deletions

View file

@ -86,8 +86,6 @@ struct ircd::m::device_list_update
json::property<name::keys, json::object>
>
{
static bool send(json::iov &content);
using super_type::tuple;
using super_type::operator=;
};
@ -119,24 +117,6 @@ struct ircd::m::device
>
{
using id = m::id::device;
using closure = std::function<void (const string_view &)>;
using closure_bool = std::function<bool (const string_view &)>;
// primary interface
static bool for_each(const user &, const closure_bool &); // each device_id
static bool for_each(const user &, const string_view &id, const closure_bool &); // each property
static bool get(std::nothrow_t, const user &, const string_view &id, const string_view &prop, const closure &);
static bool get(const user &, const string_view &id, const string_view &prop, const closure &);
static bool has(const user &, const string_view &id, const string_view &prop);
static bool has(const user &, const string_view &id);
static bool del(const user &, const string_view &id);
static bool put(const user &, const string_view &id, const string_view &prop, const string_view &val);
static bool set(const user &, const string_view &id, const string_view &prop, const string_view &val);
static bool set(const user &, const device &);
static bool set(const device_list_update &);
// composite interface
static std::map<std::string, long> count_one_time_keys(const user &, const string_view &);
using super_type::tuple;
using super_type::operator=;

View file

@ -62,6 +62,7 @@ namespace ircd
#include "hook.h"
#include "vm.h"
#include "invite_3pid.h"
#include "device.h"
#include "push.h"
#include "createroom.h"
#include "room/room.h"
@ -74,7 +75,6 @@ namespace ircd
#include "events.h"
#include "node.h"
#include "login.h"
#include "device.h"
#include "request.h"
#include "fed/fed.h"
#include "keys.h"

View file

@ -0,0 +1,44 @@
// The Construct
//
// Copyright (C) The Construct Developers, Authors & Contributors
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_M_USER_DEVICES_H
struct ircd::m::user::devices
{
using closure = std::function<void (const event::idx &, const string_view &)>;
using closure_bool = std::function<bool (const event::idx &, const string_view &)>;
m::user user;
bool for_each(const closure_bool &) const; // each device_id
bool for_each(const string_view &id, const closure_bool &) const; // each property
bool has(const string_view &id, const string_view &prop) const;
bool has(const string_view &id) const;
bool get(std::nothrow_t, const string_view &id, const string_view &prop, const closure &) const;
bool get(const string_view &id, const string_view &prop, const closure &) const;
bool put(const string_view &id, const string_view &prop, const string_view &val) const;
bool set(const string_view &id, const string_view &prop, const string_view &val) const;
bool set(const device &) const;
bool del(const string_view &id) const;
///TODO: XXX junk
static std::map<std::string, long> count_one_time_keys(const m::user &, const string_view &);
static bool update(const device_list_update &);
static bool send(json::iov &content);
devices(const m::user &user)
:user{user}
{}
};

View file

@ -46,6 +46,7 @@ struct ircd::m::user
struct pushers;
struct notifications;
struct tokens;
struct devices;
using id = m::id::user;
using closure = std::function<void (const user &)>;
@ -95,3 +96,4 @@ const
#include "pushers.h"
#include "notifications.h"
#include "tokens.h"
#include "devices.h"

View file

@ -107,8 +107,8 @@ libircd_matrix_la_SOURCES += room_server_acl.cc
libircd_matrix_la_SOURCES += room_stats.cc
libircd_matrix_la_SOURCES += user.cc
libircd_matrix_la_SOURCES += user_account_data.cc
libircd_matrix_la_SOURCES += user_devices.cc
libircd_matrix_la_SOURCES += user_events.cc
libircd_matrix_la_SOURCES += user_rooms.cc
libircd_matrix_la_SOURCES += user_filter.cc
libircd_matrix_la_SOURCES += user_ignores.cc
libircd_matrix_la_SOURCES += user_mitsein.cc
@ -119,9 +119,9 @@ libircd_matrix_la_SOURCES += user_pushrules.cc
libircd_matrix_la_SOURCES += user_register.cc
libircd_matrix_la_SOURCES += user_room_account_data.cc
libircd_matrix_la_SOURCES += user_room_tags.cc
libircd_matrix_la_SOURCES += user_rooms.cc
libircd_matrix_la_SOURCES += user_tokens.cc
libircd_matrix_la_SOURCES += breadcrumb_rooms.cc
libircd_matrix_la_SOURCES += device.cc
libircd_matrix_la_SOURCES += display_name.cc
libircd_matrix_la_SOURCES += event_append.cc
libircd_matrix_la_SOURCES += event_horizon.cc

View file

@ -1,20 +1,111 @@
// Matrix Construct
// The Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
// Copyright (C) The Construct Developers, Authors & Contributors
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
std::map<std::string, long>
ircd::m::device::count_one_time_keys(const user &user,
const string_view &device_id)
bool
ircd::m::user::devices::send(json::iov &content)
try
{
assert(content.has("user_id"));
assert(content.has("device_id"));
json::iov event;
const json::iov::push push[]
{
{ event, { "type", "m.device_list_update" } },
{ event, { "sender", content.at("user_id") } },
};
m::vm::copts opts;
opts.edu = true;
opts.prop_mask.reset();
opts.prop_mask.set("origin");
opts.notify_clients = false;
m::vm::eval
{
event, content, opts
};
return true;
}
catch(const ctx::interrupted &)
{
throw;
}
catch(const std::exception &e)
{
log::error
{
m::log, "Send m.device_list_update for '%s' belonging to %s :%s",
content.at("device_id"),
content.at("user_id"),
e.what(),
};
return false;
}
bool
ircd::m::user::devices::update(const device_list_update &update)
{
const m::user &user
{
json::at<"user_id"_>(update)
};
const m::user::devices devices
{
user
};
const auto &device_id
{
json::at<"device_id"_>(update)
};
if(json::get<"deleted"_>(update))
return devices.del(device_id);
// Properties we're interested in for now...
static const string_view mask[]
{
"device_id",
"device_display_name",
"keys",
};
bool ret {false};
json::for_each(update, mask, [&ret, &devices, &device_id]
(const auto &prop, auto &&val)
{
if constexpr(std::is_assignable<string_view, decltype(val)>())
{
if(json::defined(json::value(val)))
ret |= devices.set(device_id, prop, val);
}
});
return ret;
}
std::map<std::string, long>
ircd::m::user::devices::count_one_time_keys(const m::user &user,
const string_view &device_id)
{
const m::user::devices devices
{
user
};
std::map<std::string, long> ret;
for_each(user, device_id, [&ret]
(const string_view &type)
devices.for_each(device_id, [&ret]
(const auto &event_idx, const string_view &type)
{
if(!startswith(type, "one_time_key|"))
return true;
@ -47,112 +138,8 @@ ircd::m::device::count_one_time_keys(const user &user,
}
bool
ircd::m::device::set(const device_list_update &update)
{
const m::user &user
{
json::at<"user_id"_>(update)
};
const auto &device_id
{
json::at<"device_id"_>(update)
};
if(json::get<"deleted"_>(update))
return del(user, device_id);
// Properties we're interested in for now...
static const string_view mask[]
{
"device_id",
"device_display_name",
"keys",
};
bool ret {false};
json::for_each(update, mask, [&ret, &user, &device_id]
(const auto &prop, auto &&val)
{
if constexpr(std::is_assignable<string_view, decltype(val)>())
{
if(json::defined(json::value(val)))
ret |= set(user, device_id, prop, val);
}
});
return ret;
}
bool
ircd::m::device::set(const m::user &user,
const device &device)
{
const string_view &device_id
{
json::at<"device_id"_>(device)
};
bool ret {false};
json::for_each(device, [&user, &device_id, &ret]
(const auto &prop, auto &&val)
{
if constexpr(std::is_assignable<string_view, decltype(val)>())
{
if(json::defined(json::value(val)))
ret |= set(user, device_id, prop, val);
}
});
return ret;
}
bool
ircd::m::device::set(const m::user &user,
const string_view &id,
const string_view &prop,
const string_view &val)
{
bool dup {false};
const bool got
{
get(std::nothrow, user, id, prop, [&val, &dup]
(const json::string &existing)
{
dup = val == existing;
})
};
assert(!dup || got);
return !dup?
put(user, id, prop, val):
false;
}
bool
ircd::m::device::put(const m::user &user,
const string_view &id,
const string_view &prop,
const string_view &val)
{
char buf[m::event::TYPE_MAX_SIZE];
const string_view type{fmt::sprintf
{
buf, "ircd.device.%s", prop
}};
const user::room user_room{user};
m::send(user_room, user, type, id, json::members
{
{ "", val }
});
return true;
}
bool
ircd::m::device::del(const m::user &user,
const string_view &id)
ircd::m::user::devices::del(const string_view &id)
const
{
const user::room user_room
{
@ -190,24 +177,102 @@ ircd::m::device::del(const m::user &user,
const bool broadcasted
{
device_list_update::send(content)
user::devices::send(content)
};
return true;
}
bool
ircd::m::device::has(const m::user &user,
const string_view &id)
ircd::m::user::devices::set(const device &device)
const
{
const user::room user_room{user};
const room::state state{user_room};
const string_view &device_id
{
json::at<"device_id"_>(device)
};
bool ret {false};
json::for_each(device, [this, &device_id, &ret]
(const auto &prop, auto &&val)
{
if constexpr(std::is_assignable<string_view, decltype(val)>())
{
if(json::defined(json::value(val)))
ret |= set(device_id, prop, val);
}
});
return ret;
}
bool
ircd::m::user::devices::set(const string_view &id,
const string_view &prop,
const string_view &val)
const
{
bool dup {false};
const bool got
{
get(std::nothrow, id, prop, [&val, &dup]
(const auto &event_idx, const json::string &existing)
{
dup = val == existing;
})
};
assert(!dup || got);
return !dup?
put(id, prop, val):
false;
}
bool
ircd::m::user::devices::put(const string_view &id,
const string_view &prop,
const string_view &val)
const
{
char buf[m::event::TYPE_MAX_SIZE];
const string_view type{fmt::sprintf
{
buf, "ircd.device.%s", prop
}};
const user::room user_room
{
user
};
m::send(user_room, user, type, id, json::members
{
{ "", val }
});
return true;
}
bool
ircd::m::user::devices::has(const string_view &id)
const
{
const user::room user_room
{
user
};
const room::state state
{
user_room
};
const room::state::type_prefix type
{
"ircd.device."
};
bool ret(false);
bool ret{false};
state.for_each(type, [&state, &id, &ret]
(const string_view &type, const string_view &, const event::idx &)
{
@ -219,13 +284,13 @@ ircd::m::device::has(const m::user &user,
}
bool
ircd::m::device::has(const m::user &user,
const string_view &id,
const string_view &prop)
ircd::m::user::devices::has(const string_view &id,
const string_view &prop)
const
{
bool ret{false};
get(std::nothrow, user, id, prop, [&ret]
(const string_view &value)
get(std::nothrow, id, prop, [&ret]
(const auto &event_idx, const string_view &value)
{
ret = !empty(value);
});
@ -234,14 +299,14 @@ ircd::m::device::has(const m::user &user,
}
bool
ircd::m::device::get(const m::user &user,
const string_view &id,
const string_view &prop,
const closure &c)
ircd::m::user::devices::get(const string_view &id,
const string_view &prop,
const closure &c)
const
{
const bool ret
{
get(std::nothrow, user, id, prop, c)
get(std::nothrow, id, prop, c)
};
if(!ret)
@ -257,26 +322,29 @@ ircd::m::device::get(const m::user &user,
}
bool
ircd::m::device::get(std::nothrow_t,
const m::user &user,
const string_view &id,
const string_view &prop,
const closure &closure)
ircd::m::user::devices::get(std::nothrow_t,
const string_view &id,
const string_view &prop,
const closure &closure)
const
{
const m::user::room user_room
{
user
};
char buf[m::event::TYPE_MAX_SIZE];
const string_view type{fmt::sprintf
{
buf, "ircd.device.%s", prop
}};
const m::user::room user_room{user};
const m::room::state state{user_room};
const auto event_idx
{
state.get(std::nothrow, type, id)
user_room.get(std::nothrow, type, id)
};
return m::get(std::nothrow, event_idx, "content", [&closure]
return m::get(std::nothrow, event_idx, "content", [&event_idx, &closure]
(const json::object &content)
{
const string_view &value
@ -284,24 +352,32 @@ ircd::m::device::get(std::nothrow_t,
content.get("")
};
closure(value);
closure(event_idx, value);
});
}
bool
ircd::m::device::for_each(const m::user &user,
const string_view &device_id,
const closure_bool &closure)
ircd::m::user::devices::for_each(const string_view &device_id,
const closure_bool &closure)
const
{
const m::user::room user_room{user};
const m::room::state state{user_room};
const m::user::room user_room
{
user
};
const m::room::state state
{
user_room
};
const room::state::type_prefix type
{
"ircd.device."
};
return state.for_each(type, [&state, &device_id, &closure]
(const string_view &type, const string_view &, const event::idx &)
(const string_view &type, const string_view &, const event::idx &event_idx)
{
const string_view &prop
{
@ -309,14 +385,14 @@ ircd::m::device::for_each(const m::user &user,
};
return state.has(type, device_id)?
closure(prop):
closure(event_idx, prop):
true;
});
}
bool
ircd::m::device::for_each(const m::user &user,
const closure_bool &closure)
ircd::m::user::devices::for_each(const closure_bool &closure)
const
{
const m::user::room user_room
{
@ -329,51 +405,8 @@ ircd::m::device::for_each(const m::user &user,
};
return state.for_each("ircd.device.device_id", [&closure]
(const string_view &, const string_view &state_key, const event::idx &)
(const string_view &, const string_view &state_key, const event::idx &event_idx)
{
return closure(state_key);
return closure(event_idx, state_key);
});
}
bool
ircd::m::device_list_update::send(json::iov &content)
try
{
assert(content.has("user_id"));
assert(content.has("device_id"));
json::iov event;
const json::iov::push push[]
{
{ event, { "type", "m.direct_to_device" } },
{ event, { "sender", content.at("user_id") } },
};
m::vm::copts opts;
opts.edu = true;
opts.prop_mask.reset();
opts.prop_mask.set("origin");
opts.notify_clients = false;
m::vm::eval
{
event, content, opts
};
return true;
}
catch(const ctx::interrupted &)
{
throw;
}
catch(const std::exception &e)
{
log::error
{
m::log, "Send m.device_list_update for '%s' belonging to %s :%s",
content.at("device_id"),
content.at("user_id"),
e.what(),
};
return false;
}

View file

@ -168,16 +168,19 @@ const
})
};
const json::members device
const m::user::devices devices
{
user_id
};
devices.set(json::members
{
{ "device_id", device_id },
{ "display_name", initial_device_display_name },
{ "last_seen_ts", ircd::time<milliseconds>() },
{ "last_seen_ip", last_seen_ip },
{ "access_token_id", access_token_id },
};
m::device::set(user_id, device);
});
}
// Send response to user

View file

@ -87,8 +87,13 @@ post__delete_devices(client &client,
"Incorrect password."
};
const m::user::devices user_devices
{
request.user_id
};
for(const json::string &device_id : devices)
m::device::del(request.user_id, device_id);
user_devices.del(device_id);
return m::resource::response
{

View file

@ -11,8 +11,8 @@
using namespace ircd;
static void
_get_device(json::stack::object &obj,
const m::user &user,
_get_device(json::stack::object &,
const m::user::devices &,
const string_view &device_id);
static m::resource::response
@ -94,7 +94,12 @@ get__devices(client &client,
url::decode(device_id, request.parv[0])
};
if(!m::device::has(request.user_id, device_id))
const m::user::devices devices
{
request.user_id
};
if(!devices.has(device_id))
throw m::NOT_FOUND
{
"Device ID '%s' not found", device_id
@ -115,7 +120,7 @@ get__devices(client &client,
out
};
_get_device(top, request.user_id, device_id);
_get_device(top, devices, device_id);
return {};
}
@ -134,10 +139,18 @@ put__devices(client &client,
url::decode(device_id, request.parv[0])
};
const m::user::devices devices
{
request.user_id
};
m::device data{request.content};
json::get<"device_id"_>(data) = device_id;
m::device::set(request.user_id, data);
const bool set
{
devices.set(data)
};
return m::resource::response
{
@ -180,7 +193,15 @@ delete__devices(client &client,
"Incorrect password."
};
m::device::del(request.user_id, device_id);
const m::user::devices devices
{
request.user_id
};
const bool deleted
{
devices.del(device_id)
};
return m::resource::response
{
@ -193,6 +214,11 @@ get__devices_all(client &client,
const m::resource::request &request,
const m::room user_room)
{
const m::user::devices user_devices
{
request.user_id
};
m::resource::response::chunked response
{
client, http::OK
@ -213,11 +239,15 @@ get__devices_all(client &client,
top, "devices"
};
m::device::for_each(request.user_id, [&request, &devices]
(const string_view &device_id)
user_devices.for_each([&user_devices, &devices]
(const auto &event_idx, const string_view &device_id)
{
json::stack::object obj{devices};
_get_device(obj, request.user_id, device_id);
json::stack::object obj
{
devices
};
_get_device(obj, user_devices, device_id);
return true;
});
@ -226,7 +256,7 @@ get__devices_all(client &client,
void
_get_device(json::stack::object &obj,
const m::user &user,
const m::user::devices &devices,
const string_view &device_id)
{
json::stack::member
@ -234,8 +264,8 @@ _get_device(json::stack::object &obj,
obj, "device_id", device_id
};
m::device::get(std::nothrow, user, device_id, "display_name", [&obj]
(const string_view &value)
devices.get(std::nothrow, device_id, "display_name", [&obj]
(const auto &, const string_view &value)
{
json::stack::member
{
@ -243,8 +273,8 @@ _get_device(json::stack::object &obj,
};
});
m::device::get(std::nothrow, user, device_id, "last_seen_ip", [&obj]
(const string_view &value)
devices.get(std::nothrow, device_id, "last_seen_ip", [&obj]
(const auto &, const string_view &value)
{
json::stack::member
{
@ -252,8 +282,8 @@ _get_device(json::stack::object &obj,
};
});
m::device::get(std::nothrow, user, device_id, "last_seen_ts", [&obj]
(const string_view &value)
devices.get(std::nothrow, device_id, "last_seen_ts", [&obj]
(const auto &, const string_view &value)
{
json::stack::member
{

View file

@ -71,6 +71,11 @@ ircd::m::post_keys_signatures_upload(client &client,
_user_id
};
const m::user::devices devices
{
user_id
};
const json::object &devices_keys
{
devices_keys_
@ -101,7 +106,7 @@ ircd::m::post_keys_signatures_upload(client &client,
const bool set
{
m::device::set(user_id, _device_id, "signatures", device_keys_)
devices.set(_device_id, "signatures", device_keys_)
};
}
}

View file

@ -114,7 +114,7 @@ post__keys_upload(client &client,
const auto counts
{
m::device::count_one_time_keys(request.user_id, device_id)
m::user::devices::count_one_time_keys(request.user_id, device_id)
};
for(const auto &[algorithm, count] : counts)
@ -140,6 +140,11 @@ upload_one_time_keys(client &client,
const m::device::id &device_id,
const json::object &one_time_keys)
{
const m::user::devices devices
{
request.user_id
};
for(const auto &[ident, object] : one_time_keys)
{
const auto &[algorithm, name]
@ -160,7 +165,10 @@ upload_one_time_keys(client &client,
strlcat(state_key_buf, ident)
};
m::device::set(request.user_id, device_id, state_key, object);
const auto set
{
devices.set(device_id, state_key, object)
};
log::debug
{
@ -207,8 +215,16 @@ upload_device_keys(client &client,
at<"signatures"_>(device_keys)
};
const m::user::devices devices
{
request.user_id
};
m::device data;
json::get<"device_id"_>(data) = device_id;
json::get<"keys"_>(data) = request["device_keys"];
m::device::set(request.user_id, data);
const auto set
{
devices.set(data)
};
}

View file

@ -127,16 +127,19 @@ post__login_password(client &client,
})
};
const json::members device
const m::user::devices devices
{
user_id
};
devices.set(json::members
{
{ "device_id", device_id },
{ "display_name", initial_device_display_name },
{ "last_seen_ts", ircd::time<milliseconds>() },
{ "last_seen_ip", last_seen_ip },
{ "access_token_id", access_token_id },
};
m::device::set(user_id, device);
});
// Send response to user
return resource::response

View file

@ -82,7 +82,7 @@ ircd::m::sync::_device_one_time_keys_count(data &data)
const auto counts
{
m::device::count_one_time_keys(data.user, data.device_id)
m::user::devices::count_one_time_keys(data.user, data.device_id)
};
for(const auto &[algorithm, count] : counts)

View file

@ -11929,10 +11929,15 @@ console_cmd__user__devices(opt &out, const string_view &line)
param.at("device_id", string_view{})
};
const m::user::devices devices
{
user_id
};
if(!device_id)
{
m::device::for_each(user_id, [&out]
(const string_view &device_id)
devices.for_each([&out]
(const auto &event_idx, const string_view &device_id)
{
out << device_id << std::endl;
return true;
@ -11941,11 +11946,11 @@ console_cmd__user__devices(opt &out, const string_view &line)
return true;
}
m::device::for_each(user_id, device_id, [&out, &user_id, &device_id]
(const string_view &prop)
devices.for_each(device_id, [&out, &devices, &device_id]
(const auto &event_idx, const string_view &prop)
{
m::device::get(std::nothrow, user_id, device_id, prop, [&out, &prop]
(const string_view &value)
devices.get(std::nothrow, device_id, prop, [&out, &prop]
(const auto &event_idx, const string_view &value)
{
out << prop << ": "
<< value

View file

@ -54,6 +54,11 @@ get__user_devices(client &client,
url::decode(user_id, request.parv[0])
};
const m::user::devices user_devices
{
user_id
};
m::resource::response::chunked response
{
client, http::OK
@ -84,8 +89,8 @@ get__user_devices(client &client,
top, "devices"
};
m::device::for_each(user_id, [&devices, &user_id]
(const string_view &device_id)
user_devices.for_each([&user_devices, &devices]
(const auto &, const string_view &device_id)
{
json::stack::object device
{
@ -99,17 +104,17 @@ get__user_devices(client &client,
// The property name difference here is on purpose, probably one of
// those so-called spec "thinkos"
m::device::get(std::nothrow, user_id, device_id, "display_name", [&device]
(const string_view &value)
user_devices.get(std::nothrow, device_id, "display_name", [&device]
(const auto &, const json::string &value)
{
json::stack::member
{
device, "device_display_name", unquote(value)
device, "device_display_name", value
};
});
m::device::get(std::nothrow, user_id, device_id, "keys", [&device]
(const json::object &value)
user_devices.get(std::nothrow, device_id, "keys", [&device]
(const auto &, const json::object &value)
{
json::stack::member
{

View file

@ -26,9 +26,9 @@ user_keys_query_resource
};
static void
_query_user_device(client &client,
const m::resource::request &request,
const m::user::id &user_id,
_query_user_device(client &,
const m::resource::request &,
const m::user::devices &,
const string_view &device_id,
json::stack::object &out);
@ -70,25 +70,38 @@ post__user_keys_query(client &client,
top, "device_keys"
};
for(const auto &m : request_keys)
for(const auto &[user_id_, device_ids_] : request_keys)
{
const m::user::id &user_id{m.first};
const json::array &device_ids{m.second};
const m::user::id &user_id
{
user_id_
};
const json::array &device_ids
{
device_ids_
};
const m::user::devices devices
{
user_id
};
json::stack::object response_keys_user
{
response_keys, user_id
};
if(empty(device_ids))
m::device::for_each(user_id, [&client, &request, &user_id, &response_keys_user]
(const string_view &device_id)
devices.for_each([&client, &request, &devices, &response_keys_user]
(const auto &event_idx, const string_view &device_id)
{
_query_user_device(client, request, user_id, device_id, response_keys_user);
_query_user_device(client, request, devices, device_id, response_keys_user);
return true;
});
else
for(const json::string &device_id : device_ids)
_query_user_device(client, request, user_id, device_id, response_keys_user);
_query_user_device(client, request, devices, device_id, response_keys_user);
}
return std::move(response);
@ -97,11 +110,11 @@ post__user_keys_query(client &client,
void
_query_user_device(client &client,
const m::resource::request &request,
const m::user::id &user_id,
const m::user::devices &devices,
const string_view &device_id,
json::stack::object &out)
{
if(!m::device::has(user_id, device_id, "keys"))
if(!devices.has(device_id, "keys"))
return;
json::stack::object object
@ -109,8 +122,8 @@ _query_user_device(client &client,
out, device_id
};
m::device::get(std::nothrow, user_id, device_id, "keys", [&device_id, &object]
(const json::object &device_keys)
devices.get(std::nothrow, device_id, "keys", [&device_id, &object]
(const auto &event_idx, const json::object &device_keys)
{
for(const auto &member : device_keys)
json::stack::member
@ -119,8 +132,8 @@ _query_user_device(client &client,
};
});
m::device::get(std::nothrow, user_id, device_id, "display_name", [&device_id, &object]
(const string_view &display_name)
devices.get(std::nothrow, device_id, "display_name", [&device_id, &object]
(const auto &event_idx, const string_view &display_name)
{
json::stack::object non_hancock
{

View file

@ -58,7 +58,7 @@ try
const bool updated
{
m::device::set(update)
m::user::devices::update(update)
};
if(!updated)