0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-25 23:14:13 +01: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> json::property<name::keys, json::object>
> >
{ {
static bool send(json::iov &content);
using super_type::tuple; using super_type::tuple;
using super_type::operator=; using super_type::operator=;
}; };
@ -119,24 +117,6 @@ struct ircd::m::device
> >
{ {
using id = m::id::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::tuple;
using super_type::operator=; using super_type::operator=;

View file

@ -62,6 +62,7 @@ namespace ircd
#include "hook.h" #include "hook.h"
#include "vm.h" #include "vm.h"
#include "invite_3pid.h" #include "invite_3pid.h"
#include "device.h"
#include "push.h" #include "push.h"
#include "createroom.h" #include "createroom.h"
#include "room/room.h" #include "room/room.h"
@ -74,7 +75,6 @@ namespace ircd
#include "events.h" #include "events.h"
#include "node.h" #include "node.h"
#include "login.h" #include "login.h"
#include "device.h"
#include "request.h" #include "request.h"
#include "fed/fed.h" #include "fed/fed.h"
#include "keys.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 pushers;
struct notifications; struct notifications;
struct tokens; struct tokens;
struct devices;
using id = m::id::user; using id = m::id::user;
using closure = std::function<void (const user &)>; using closure = std::function<void (const user &)>;
@ -95,3 +96,4 @@ const
#include "pushers.h" #include "pushers.h"
#include "notifications.h" #include "notifications.h"
#include "tokens.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 += room_stats.cc
libircd_matrix_la_SOURCES += user.cc libircd_matrix_la_SOURCES += user.cc
libircd_matrix_la_SOURCES += user_account_data.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_events.cc
libircd_matrix_la_SOURCES += user_rooms.cc
libircd_matrix_la_SOURCES += user_filter.cc libircd_matrix_la_SOURCES += user_filter.cc
libircd_matrix_la_SOURCES += user_ignores.cc libircd_matrix_la_SOURCES += user_ignores.cc
libircd_matrix_la_SOURCES += user_mitsein.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_register.cc
libircd_matrix_la_SOURCES += user_room_account_data.cc libircd_matrix_la_SOURCES += user_room_account_data.cc
libircd_matrix_la_SOURCES += user_room_tags.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 += user_tokens.cc
libircd_matrix_la_SOURCES += breadcrumb_rooms.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 += display_name.cc
libircd_matrix_la_SOURCES += event_append.cc libircd_matrix_la_SOURCES += event_append.cc
libircd_matrix_la_SOURCES += event_horizon.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) The Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net> // Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The // copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file. // full license for this software is available in the LICENSE file.
std::map<std::string, long> bool
ircd::m::device::count_one_time_keys(const user &user, ircd::m::user::devices::send(json::iov &content)
const string_view &device_id) 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; std::map<std::string, long> ret;
for_each(user, device_id, [&ret] devices.for_each(device_id, [&ret]
(const string_view &type) (const auto &event_idx, const string_view &type)
{ {
if(!startswith(type, "one_time_key|")) if(!startswith(type, "one_time_key|"))
return true; return true;
@ -47,112 +138,8 @@ ircd::m::device::count_one_time_keys(const user &user,
} }
bool bool
ircd::m::device::set(const device_list_update &update) ircd::m::user::devices::del(const string_view &id)
{ const
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)
{ {
const user::room user_room const user::room user_room
{ {
@ -190,24 +177,102 @@ ircd::m::device::del(const m::user &user,
const bool broadcasted const bool broadcasted
{ {
device_list_update::send(content) user::devices::send(content)
}; };
return true; return true;
} }
bool bool
ircd::m::device::has(const m::user &user, ircd::m::user::devices::set(const device &device)
const string_view &id) const
{ {
const user::room user_room{user}; const string_view &device_id
const room::state state{user_room}; {
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 const room::state::type_prefix type
{ {
"ircd.device." "ircd.device."
}; };
bool ret(false); bool ret{false};
state.for_each(type, [&state, &id, &ret] state.for_each(type, [&state, &id, &ret]
(const string_view &type, const string_view &, const event::idx &) (const string_view &type, const string_view &, const event::idx &)
{ {
@ -219,13 +284,13 @@ ircd::m::device::has(const m::user &user,
} }
bool bool
ircd::m::device::has(const m::user &user, ircd::m::user::devices::has(const string_view &id,
const string_view &id, const string_view &prop)
const string_view &prop) const
{ {
bool ret{false}; bool ret{false};
get(std::nothrow, user, id, prop, [&ret] get(std::nothrow, id, prop, [&ret]
(const string_view &value) (const auto &event_idx, const string_view &value)
{ {
ret = !empty(value); ret = !empty(value);
}); });
@ -234,14 +299,14 @@ ircd::m::device::has(const m::user &user,
} }
bool bool
ircd::m::device::get(const m::user &user, ircd::m::user::devices::get(const string_view &id,
const string_view &id, const string_view &prop,
const string_view &prop, const closure &c)
const closure &c) const
{ {
const bool ret const bool ret
{ {
get(std::nothrow, user, id, prop, c) get(std::nothrow, id, prop, c)
}; };
if(!ret) if(!ret)
@ -257,26 +322,29 @@ ircd::m::device::get(const m::user &user,
} }
bool bool
ircd::m::device::get(std::nothrow_t, ircd::m::user::devices::get(std::nothrow_t,
const m::user &user, const string_view &id,
const string_view &id, const string_view &prop,
const string_view &prop, const closure &closure)
const closure &closure) const
{ {
const m::user::room user_room
{
user
};
char buf[m::event::TYPE_MAX_SIZE]; char buf[m::event::TYPE_MAX_SIZE];
const string_view type{fmt::sprintf const string_view type{fmt::sprintf
{ {
buf, "ircd.device.%s", prop buf, "ircd.device.%s", prop
}}; }};
const m::user::room user_room{user};
const m::room::state state{user_room};
const auto event_idx 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 json::object &content)
{ {
const string_view &value const string_view &value
@ -284,24 +352,32 @@ ircd::m::device::get(std::nothrow_t,
content.get("") content.get("")
}; };
closure(value); closure(event_idx, value);
}); });
} }
bool bool
ircd::m::device::for_each(const m::user &user, ircd::m::user::devices::for_each(const string_view &device_id,
const string_view &device_id, const closure_bool &closure)
const closure_bool &closure) const
{ {
const m::user::room user_room{user}; const m::user::room user_room
const m::room::state state{user_room}; {
user
};
const m::room::state state
{
user_room
};
const room::state::type_prefix type const room::state::type_prefix type
{ {
"ircd.device." "ircd.device."
}; };
return state.for_each(type, [&state, &device_id, &closure] 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 const string_view &prop
{ {
@ -309,14 +385,14 @@ ircd::m::device::for_each(const m::user &user,
}; };
return state.has(type, device_id)? return state.has(type, device_id)?
closure(prop): closure(event_idx, prop):
true; true;
}); });
} }
bool bool
ircd::m::device::for_each(const m::user &user, ircd::m::user::devices::for_each(const closure_bool &closure)
const closure_bool &closure) const
{ {
const m::user::room user_room 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] 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 }, { "device_id", device_id },
{ "display_name", initial_device_display_name }, { "display_name", initial_device_display_name },
{ "last_seen_ts", ircd::time<milliseconds>() }, { "last_seen_ts", ircd::time<milliseconds>() },
{ "last_seen_ip", last_seen_ip }, { "last_seen_ip", last_seen_ip },
{ "access_token_id", access_token_id }, { "access_token_id", access_token_id },
}; });
m::device::set(user_id, device);
} }
// Send response to user // Send response to user

View file

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

View file

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

View file

@ -71,6 +71,11 @@ ircd::m::post_keys_signatures_upload(client &client,
_user_id _user_id
}; };
const m::user::devices devices
{
user_id
};
const json::object &devices_keys const json::object &devices_keys
{ {
devices_keys_ devices_keys_
@ -101,7 +106,7 @@ ircd::m::post_keys_signatures_upload(client &client,
const bool set 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 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) for(const auto &[algorithm, count] : counts)
@ -140,6 +140,11 @@ upload_one_time_keys(client &client,
const m::device::id &device_id, const m::device::id &device_id,
const json::object &one_time_keys) const json::object &one_time_keys)
{ {
const m::user::devices devices
{
request.user_id
};
for(const auto &[ident, object] : one_time_keys) for(const auto &[ident, object] : one_time_keys)
{ {
const auto &[algorithm, name] const auto &[algorithm, name]
@ -160,7 +165,10 @@ upload_one_time_keys(client &client,
strlcat(state_key_buf, ident) 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 log::debug
{ {
@ -207,8 +215,16 @@ upload_device_keys(client &client,
at<"signatures"_>(device_keys) at<"signatures"_>(device_keys)
}; };
const m::user::devices devices
{
request.user_id
};
m::device data; m::device data;
json::get<"device_id"_>(data) = device_id; json::get<"device_id"_>(data) = device_id;
json::get<"keys"_>(data) = request["device_keys"]; 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 }, { "device_id", device_id },
{ "display_name", initial_device_display_name }, { "display_name", initial_device_display_name },
{ "last_seen_ts", ircd::time<milliseconds>() }, { "last_seen_ts", ircd::time<milliseconds>() },
{ "last_seen_ip", last_seen_ip }, { "last_seen_ip", last_seen_ip },
{ "access_token_id", access_token_id }, { "access_token_id", access_token_id },
}; });
m::device::set(user_id, device);
// Send response to user // Send response to user
return resource::response return resource::response

View file

@ -82,7 +82,7 @@ ircd::m::sync::_device_one_time_keys_count(data &data)
const auto counts 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) 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{}) param.at("device_id", string_view{})
}; };
const m::user::devices devices
{
user_id
};
if(!device_id) if(!device_id)
{ {
m::device::for_each(user_id, [&out] devices.for_each([&out]
(const string_view &device_id) (const auto &event_idx, const string_view &device_id)
{ {
out << device_id << std::endl; out << device_id << std::endl;
return true; return true;
@ -11941,11 +11946,11 @@ console_cmd__user__devices(opt &out, const string_view &line)
return true; return true;
} }
m::device::for_each(user_id, device_id, [&out, &user_id, &device_id] devices.for_each(device_id, [&out, &devices, &device_id]
(const string_view &prop) (const auto &event_idx, const string_view &prop)
{ {
m::device::get(std::nothrow, user_id, device_id, prop, [&out, &prop] devices.get(std::nothrow, device_id, prop, [&out, &prop]
(const string_view &value) (const auto &event_idx, const string_view &value)
{ {
out << prop << ": " out << prop << ": "
<< value << value

View file

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

View file

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

View file

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