Implement permission manage web UI
This commit is contained in:
@@ -866,6 +866,38 @@ namespace confighttp {
|
||||
outputTree.put("status", true);
|
||||
}
|
||||
|
||||
void
|
||||
updateClient(resp_https_t response, req_https_t request) {
|
||||
if (!authenticate(response, request)) return;
|
||||
|
||||
print_req(request);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << request->content.rdbuf();
|
||||
|
||||
pt::ptree inputTree, outputTree;
|
||||
|
||||
auto g = util::fail_guard([&]() {
|
||||
std::ostringstream data;
|
||||
pt::write_json(data, outputTree);
|
||||
response->write(data.str());
|
||||
});
|
||||
|
||||
try {
|
||||
pt::read_json(ss, inputTree);
|
||||
std::string uuid = inputTree.get<std::string>("uuid");
|
||||
std::string name = inputTree.get<std::string>("name");
|
||||
auto perm = (crypto::PERM)inputTree.get<uint32_t>("perm") & crypto::PERM::_all;
|
||||
outputTree.put("status", nvhttp::update_device_info(uuid, name, perm));
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
BOOST_LOG(warning) << "Update Client: "sv << e.what();
|
||||
outputTree.put("status", false);
|
||||
outputTree.put("error", e.what());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unpair(resp_https_t response, req_https_t request) {
|
||||
if (!authenticate(response, request)) return;
|
||||
@@ -897,6 +929,35 @@ namespace confighttp {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
disconnect(resp_https_t response, req_https_t request) {
|
||||
if (!authenticate(response, request)) return;
|
||||
|
||||
print_req(request);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << request->content.rdbuf();
|
||||
|
||||
pt::ptree inputTree, outputTree;
|
||||
|
||||
auto g = util::fail_guard([&]() {
|
||||
std::ostringstream data;
|
||||
pt::write_json(data, outputTree);
|
||||
response->write(data.str());
|
||||
});
|
||||
|
||||
try {
|
||||
pt::read_json(ss, inputTree);
|
||||
std::string uuid = inputTree.get<std::string>("uuid");
|
||||
outputTree.put("status", nvhttp::find_and_stop_session(uuid, true));
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
BOOST_LOG(warning) << "Disconnect: "sv << e.what();
|
||||
outputTree.put("status", false);
|
||||
outputTree.put("error", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
listClients(resp_https_t response, req_https_t request) {
|
||||
if (!authenticate(response, request)) return;
|
||||
@@ -969,7 +1030,9 @@ namespace confighttp {
|
||||
server.resource["^/api/apps/([0-9]+)$"]["DELETE"] = deleteApp;
|
||||
server.resource["^/api/clients/unpair-all$"]["POST"] = unpairAll;
|
||||
server.resource["^/api/clients/list$"]["GET"] = listClients;
|
||||
server.resource["^/api/clients/update$"]["POST"] = updateClient;
|
||||
server.resource["^/api/clients/unpair$"]["POST"] = unpair;
|
||||
server.resource["^/api/clients/disconnect$"]["POST"] = disconnect;
|
||||
server.resource["^/api/apps/close$"]["POST"] = closeApp;
|
||||
server.resource["^/api/covers/upload$"]["POST"] = uploadCover;
|
||||
server.resource["^/images/apollo.ico$"]["GET"] = getFaviconImage;
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace crypto {
|
||||
list = _action << 0, // Allow list apps
|
||||
view = _action << 1, // Allow view streams
|
||||
launch = _action << 2, // Allow launch apps
|
||||
_allow_view = view | launch, // If no view permission is granted, disconnect the device upon permission update
|
||||
_all_actions = list | view | launch,
|
||||
|
||||
_default = view | list, // Default permissions for new clients
|
||||
|
||||
104
src/nvhttp.cpp
104
src/nvhttp.cpp
@@ -31,6 +31,7 @@
|
||||
#include "platform/common.h"
|
||||
#include "process.h"
|
||||
#include "rtsp.h"
|
||||
#include "stream.h"
|
||||
#include "system_tray.h"
|
||||
#include "utility.h"
|
||||
#include "uuid.h"
|
||||
@@ -331,7 +332,12 @@ namespace nvhttp {
|
||||
void
|
||||
add_authorized_client(const p_named_cert_t& named_cert_p) {
|
||||
client_t &client = client_root;
|
||||
client.named_devices.emplace_back(named_cert_p);
|
||||
client.named_devices.push_back(named_cert_p);
|
||||
|
||||
|
||||
#if defined SUNSHINE_TRAY && SUNSHINE_TRAY >= 1
|
||||
system_tray::update_tray_paired(named_cert_p->name);
|
||||
#endif
|
||||
|
||||
if (!config::sunshine.flags[config::flag::FRESH_STATE]) {
|
||||
save_state();
|
||||
@@ -657,10 +663,6 @@ namespace nvhttp {
|
||||
|
||||
if (hash.to_string_view() == it->second) {
|
||||
|
||||
#if defined SUNSHINE_TRAY && SUNSHINE_TRAY >= 1
|
||||
system_tray::update_tray_otp_pair(ptr->second.client.name);
|
||||
#endif
|
||||
|
||||
if (!otp_device_name.empty()) {
|
||||
ptr->second.client.name = std::move(otp_device_name);
|
||||
}
|
||||
@@ -823,7 +825,7 @@ namespace nvhttp {
|
||||
|
||||
#ifdef _WIN32
|
||||
tree.put("root.VirtualDisplayCapable", true);
|
||||
if (!!(named_cert_p->perm & PERM::list)) {
|
||||
if (!!(named_cert_p->perm & PERM::_all_actions)) {
|
||||
tree.put("root.VirtualDisplayDriverReady", proc::vDisplayDriverStatus == VDISPLAY::DRIVER_STATUS::OK);
|
||||
} else {
|
||||
tree.put("root.VirtualDisplayDriverReady", true);
|
||||
@@ -902,11 +904,29 @@ namespace nvhttp {
|
||||
get_all_clients() {
|
||||
pt::ptree named_cert_nodes;
|
||||
client_t &client = client_root;
|
||||
|
||||
std::list<std::string> connected_uuids = rtsp_stream::get_all_session_uuids();
|
||||
|
||||
for (auto &named_cert_p : client.named_devices) {
|
||||
pt::ptree named_cert_node;
|
||||
named_cert_node.put("name"s, named_cert_p->name);
|
||||
named_cert_node.put("uuid"s, named_cert_p->uuid);
|
||||
named_cert_node.put("perm", (uint32_t)named_cert_p->perm);
|
||||
|
||||
if (connected_uuids.empty()) {
|
||||
named_cert_node.put("connected"s, false);
|
||||
} else {
|
||||
bool connected = false;
|
||||
for (auto it = connected_uuids.begin(); it != connected_uuids.end(); ++it) {
|
||||
if (*it == named_cert_p->uuid) {
|
||||
connected = true;
|
||||
connected_uuids.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
named_cert_node.put("connected"s, connected);
|
||||
}
|
||||
|
||||
named_cert_nodes.push_back(std::make_pair(""s, named_cert_node));
|
||||
}
|
||||
|
||||
@@ -932,7 +952,7 @@ namespace nvhttp {
|
||||
apps.put("<xmlattr>.status_code", 200);
|
||||
|
||||
auto named_cert_p = get_verified_cert(request);
|
||||
if (!!(named_cert_p->perm & PERM::list)) {
|
||||
if (!!(named_cert_p->perm & PERM::_all_actions)) {
|
||||
for (auto &proc : proc::proc.get_apps()) {
|
||||
pt::ptree app;
|
||||
|
||||
@@ -949,7 +969,7 @@ namespace nvhttp {
|
||||
|
||||
app.put("IsHdrSupported"s, 0);
|
||||
app.put("AppTitle"s, "Permission Denied");
|
||||
app.put("ID", "PERMISSION_DENIED");
|
||||
app.put("ID", "1145141919810");
|
||||
|
||||
apps.push_back(std::make_pair("App", std::move(app)));
|
||||
|
||||
@@ -1080,7 +1100,7 @@ namespace nvhttp {
|
||||
});
|
||||
|
||||
auto named_cert_p = get_verified_cert(request);
|
||||
if (!(named_cert_p->perm & PERM::view)) {
|
||||
if (!(named_cert_p->perm & PERM::_allow_view)) {
|
||||
BOOST_LOG(debug) << "Permission ViewApp denied for [" << named_cert_p->name << "] (" << (uint32_t)named_cert_p->perm << ")";
|
||||
|
||||
tree.put("root.resume", 0);
|
||||
@@ -1161,6 +1181,10 @@ namespace nvhttp {
|
||||
tree.put("root.resume", 1);
|
||||
|
||||
rtsp_stream::launch_session_raise(launch_session);
|
||||
|
||||
#if defined SUNSHINE_TRAY && SUNSHINE_TRAY >= 1
|
||||
system_tray::update_tray_client_connected(named_cert_p->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1216,7 +1240,7 @@ namespace nvhttp {
|
||||
|
||||
auto named_cert_p = get_verified_cert(request);
|
||||
|
||||
if (!(named_cert_p->perm & PERM::list)) {
|
||||
if (!(named_cert_p->perm & PERM::_all_actions)) {
|
||||
BOOST_LOG(debug) << "Permission Get AppAsset denied for [" << named_cert_p->name << "] (" << (uint32_t)named_cert_p->perm << ")";
|
||||
|
||||
fg.disable();
|
||||
@@ -1383,6 +1407,54 @@ namespace nvhttp {
|
||||
load_state();
|
||||
}
|
||||
|
||||
void stop_session(stream::session_t& session, bool graceful) {
|
||||
if (graceful) {
|
||||
stream::session::graceful_stop(session);
|
||||
} else {
|
||||
stream::session::stop(session);
|
||||
}
|
||||
}
|
||||
|
||||
bool find_and_stop_session(const std::string& uuid, bool graceful) {
|
||||
auto session = rtsp_stream::find_session(uuid);
|
||||
if (session) {
|
||||
stop_session(*session, graceful);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void update_session_info(stream::session_t& session, const std::string& name, const crypto::PERM newPerm) {
|
||||
stream::session::update_device_info(session, name, newPerm);
|
||||
}
|
||||
|
||||
bool find_and_udpate_session_info(const std::string& uuid, const std::string& name, const crypto::PERM newPerm) {
|
||||
auto session = rtsp_stream::find_session(uuid);
|
||||
if (session) {
|
||||
update_session_info(*session, name, newPerm);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool update_device_info(const std::string& uuid, const std::string& name, const crypto::PERM newPerm) {
|
||||
find_and_udpate_session_info(uuid, name, newPerm);
|
||||
|
||||
client_t &client = client_root;
|
||||
auto it = client.named_devices.begin();
|
||||
for (; it != client.named_devices.end(); ++it) {
|
||||
auto named_cert_p = *it;
|
||||
if (named_cert_p->uuid == uuid) {
|
||||
named_cert_p->name = name;
|
||||
named_cert_p->perm = newPerm;
|
||||
save_state();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int
|
||||
unpair_client(std::string uuid) {
|
||||
int removed = 0;
|
||||
@@ -1399,6 +1471,18 @@ namespace nvhttp {
|
||||
|
||||
save_state();
|
||||
load_state();
|
||||
|
||||
if (removed) {
|
||||
auto session = rtsp_stream::find_session(uuid);
|
||||
if (session) {
|
||||
stop_session(*session, true);
|
||||
}
|
||||
|
||||
if (client.named_devices.empty()) {
|
||||
proc::proc.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
} // namespace nvhttp
|
||||
|
||||
45
src/nvhttp.h
45
src/nvhttp.h
@@ -13,6 +13,8 @@
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
// local includes
|
||||
#include "crypto.h"
|
||||
#include "rtsp.h"
|
||||
#include "thread_safe.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
@@ -96,4 +98,47 @@ namespace nvhttp {
|
||||
*/
|
||||
void
|
||||
erase_all_clients();
|
||||
|
||||
/**
|
||||
* @brief Stops a session.
|
||||
*
|
||||
* @param session The session
|
||||
* @param[in] graceful Whether to stop gracefully
|
||||
*/
|
||||
void stop_session(stream::session_t& session, bool graceful);
|
||||
|
||||
/**
|
||||
* @brief Finds and stop session.
|
||||
*
|
||||
* @param[in] uuid The uuid string
|
||||
* @param[in] graceful Whether to stop gracefully
|
||||
*/
|
||||
bool find_and_stop_session(const std::string& uuid, bool graceful);
|
||||
|
||||
/**
|
||||
* @brief Update device info associated to the session
|
||||
*
|
||||
* @param session The session
|
||||
* @param[in] name New name
|
||||
* @param[in] newPerm New permission
|
||||
*/
|
||||
void update_session_info(stream::session_t& session, const std::string& name, const crypto::PERM newPerm);
|
||||
|
||||
/**
|
||||
* @brief Finds and udpate session information.
|
||||
*
|
||||
* @param[in] uuid The uuid string
|
||||
* @param[in] name New name
|
||||
* @param[in] newPerm New permission
|
||||
*/
|
||||
bool find_and_udpate_session_info(const std::string& uuid, const std::string& name, const crypto::PERM newPerm);
|
||||
|
||||
/**
|
||||
* @brief Update device info
|
||||
*
|
||||
* @param[in] uuid The uuid string
|
||||
* @param[in] name New name
|
||||
* @param[in] newPerm New permission
|
||||
*/
|
||||
bool update_device_info(const std::string& uuid, const std::string& name, const crypto::PERM newPerm);
|
||||
} // namespace nvhttp
|
||||
|
||||
35
src/rtsp.cpp
35
src/rtsp.cpp
@@ -618,6 +618,31 @@ namespace rtsp_stream {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<stream::session_t>
|
||||
find_session(const std::string& uuid) {
|
||||
auto lg = _session_slots.lock();
|
||||
|
||||
for (auto &slot : *_session_slots) {
|
||||
if (slot && stream::session::uuid_match(*slot, uuid)) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::list<std::string>
|
||||
get_all_session_uuids() {
|
||||
std::list<std::string> uuids;
|
||||
auto lg = _session_slots.lock();
|
||||
for (auto &slot : *_session_slots) {
|
||||
if (slot) {
|
||||
uuids.push_back(stream::session::uuid(*slot));
|
||||
}
|
||||
}
|
||||
return uuids;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string_view, cmd_func_t> _map_cmd_cb;
|
||||
|
||||
@@ -652,6 +677,16 @@ namespace rtsp_stream {
|
||||
return server.session_count();
|
||||
}
|
||||
|
||||
std::shared_ptr<stream::session_t>
|
||||
find_session(const std::string& uuid) {
|
||||
return server.find_session(uuid);
|
||||
}
|
||||
|
||||
std::list<std::string>
|
||||
get_all_session_uuids() {
|
||||
return server.get_all_session_uuids();
|
||||
}
|
||||
|
||||
int
|
||||
send(tcp::socket &sock, const std::string_view &sv) {
|
||||
std::size_t bytes_send = 0;
|
||||
|
||||
12
src/rtsp.h
12
src/rtsp.h
@@ -5,10 +5,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
#include "crypto.h"
|
||||
#include "thread_safe.h"
|
||||
|
||||
// Resolve circular dependencies
|
||||
namespace stream {
|
||||
struct session_t;
|
||||
}
|
||||
|
||||
namespace rtsp_stream {
|
||||
constexpr auto RTSP_SETUP_PORT = 21;
|
||||
|
||||
@@ -60,6 +66,12 @@ namespace rtsp_stream {
|
||||
int
|
||||
session_count();
|
||||
|
||||
std::shared_ptr<stream::session_t>
|
||||
find_session(const std::string& uuid);
|
||||
|
||||
std::list<std::string>
|
||||
get_all_session_uuids();
|
||||
|
||||
void
|
||||
rtpThread();
|
||||
|
||||
|
||||
@@ -1969,6 +1969,40 @@ namespace stream {
|
||||
return session.state.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
inline bool
|
||||
send(session_t& session, const std::string_view &payload) {
|
||||
return session.broadcast_ref->control_server.send(payload, session.control.peer);
|
||||
}
|
||||
|
||||
std::string
|
||||
uuid(const session_t& session) {
|
||||
return session.device_uuid;
|
||||
}
|
||||
|
||||
bool
|
||||
uuid_match(const session_t &session, const std::string& uuid) {
|
||||
return session.device_uuid == uuid;
|
||||
}
|
||||
|
||||
bool
|
||||
update_device_info(session_t& session, const std::string& name, const crypto::PERM& newPerm) {
|
||||
session.permission = newPerm;
|
||||
if (!(newPerm & crypto::PERM::_allow_view)) {
|
||||
BOOST_LOG(debug) << "Session: View permission revoked for [" << session.device_name << "], disconnecting...";
|
||||
graceful_stop(session);
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_LOG(debug) << "Session: Permission updated for [" << session.device_name << "]";
|
||||
|
||||
if (session.device_name != name) {
|
||||
BOOST_LOG(debug) << "Session: Device name changed from [" << session.device_name << "] to [" << name << "]";
|
||||
session.device_name = name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
stop(session_t &session) {
|
||||
while_starting_do_nothing(session.state);
|
||||
@@ -1981,6 +2015,40 @@ namespace stream {
|
||||
session.shutdown_event->raise(true);
|
||||
}
|
||||
|
||||
void
|
||||
graceful_stop(session_t& session) {
|
||||
while_starting_do_nothing(session.state);
|
||||
auto expected = state_e::RUNNING;
|
||||
auto already_stopping = !session.state.compare_exchange_strong(expected, state_e::STOPPING);
|
||||
if (already_stopping) {
|
||||
return;
|
||||
}
|
||||
|
||||
// reason: graceful termination
|
||||
std::uint32_t reason = 0x80030023;
|
||||
|
||||
control_terminate_t plaintext;
|
||||
plaintext.header.type = packetTypes[IDX_TERMINATION];
|
||||
plaintext.header.payloadLength = sizeof(plaintext.ec);
|
||||
plaintext.ec = util::endian::big<uint32_t>(reason);
|
||||
|
||||
// We may not have gotten far enough to have an ENet connection yet
|
||||
if (session.control.peer) {
|
||||
std::array<std::uint8_t,
|
||||
sizeof(control_encrypted_t) + crypto::cipher::round_to_pkcs7_padded(sizeof(plaintext)) + crypto::cipher::tag_size>
|
||||
encrypted_payload;
|
||||
auto payload = stream::encode_control(&session, util::view(plaintext), encrypted_payload);
|
||||
|
||||
if (send(session, payload)) {
|
||||
TUPLE_2D(port, addr, platf::from_sockaddr_ex((sockaddr *) &session.control.peer->address.address));
|
||||
BOOST_LOG(warning) << "Couldn't send termination code to ["sv << addr << ':' << port << ']';
|
||||
}
|
||||
}
|
||||
|
||||
session.shutdown_event->raise(true);
|
||||
session.controlEnd.raise(true);
|
||||
}
|
||||
|
||||
void
|
||||
join(session_t &session) {
|
||||
// Current Nvidia drivers have a bug where NVENC can deadlock the encoder thread with hardware-accelerated
|
||||
|
||||
10
src/stream.h
10
src/stream.h
@@ -43,13 +43,23 @@ namespace stream {
|
||||
|
||||
std::shared_ptr<session_t>
|
||||
alloc(config_t &config, rtsp_stream::launch_session_t &launch_session);
|
||||
std::string
|
||||
uuid(const session_t& session);
|
||||
bool
|
||||
uuid_match(const session_t& session, const std::string& uuid);
|
||||
bool
|
||||
update_device_info(session_t& session, const std::string& name, const crypto::PERM& newPerm);
|
||||
int
|
||||
start(session_t &session, const std::string &addr_string);
|
||||
void
|
||||
stop(session_t &session);
|
||||
void
|
||||
graceful_stop(session_t& session);
|
||||
void
|
||||
join(session_t &session);
|
||||
state_e
|
||||
state(session_t &session);
|
||||
inline bool
|
||||
send(session_t& session);
|
||||
} // namespace session
|
||||
} // namespace stream
|
||||
|
||||
@@ -268,8 +268,8 @@ namespace system_tray {
|
||||
snprintf(msg, std::size(msg), "Streaming started for %s", app_name.c_str());
|
||||
snprintf(force_close_msg, std::size(force_close_msg), "Force close [%s]", app_name.c_str());
|
||||
#ifdef _WIN32
|
||||
strcpy(msg, convertUtf8ToCurrentCodepage(msg).c_str());
|
||||
strcpy(force_close_msg, convertUtf8ToCurrentCodepage(force_close_msg).c_str());
|
||||
strncpy(msg, convertUtf8ToCurrentCodepage(msg).c_str(), std::size(msg) - 1);
|
||||
strncpy(force_close_msg, convertUtf8ToCurrentCodepage(force_close_msg).c_str(), std::size(force_close_msg) - 1);
|
||||
#endif
|
||||
tray.notification_text = msg;
|
||||
tray.notification_icon = TRAY_ICON_PLAYING;
|
||||
@@ -293,7 +293,7 @@ namespace system_tray {
|
||||
char msg[256];
|
||||
snprintf(msg, std::size(msg), "Streaming paused for %s", app_name.c_str());
|
||||
#ifdef _WIN32
|
||||
strcpy(msg, convertUtf8ToCurrentCodepage(msg).c_str());
|
||||
strncpy(msg, convertUtf8ToCurrentCodepage(msg).c_str(), std::size(msg) - 1);
|
||||
#endif
|
||||
tray.icon = TRAY_ICON_PAUSING;
|
||||
tray.notification_title = "Stream Paused";
|
||||
@@ -318,7 +318,7 @@ namespace system_tray {
|
||||
char msg[256];
|
||||
snprintf(msg, std::size(msg), "Streaming stopped for %s", app_name.c_str());
|
||||
#ifdef _WIN32
|
||||
strcpy(msg, convertUtf8ToCurrentCodepage(msg).c_str());
|
||||
strncpy(msg, convertUtf8ToCurrentCodepage(msg).c_str(), std::size(msg) - 1);
|
||||
#endif
|
||||
tray.icon = TRAY_ICON;
|
||||
tray.notification_icon = TRAY_ICON;
|
||||
@@ -344,7 +344,7 @@ namespace system_tray {
|
||||
char msg[256];
|
||||
snprintf(msg, std::size(msg), "Application %s exited too fast with code %d. Click here to terminate the stream.", app_name.c_str(), exit_code);
|
||||
#ifdef _WIN32
|
||||
strcpy(msg, convertUtf8ToCurrentCodepage(msg).c_str());
|
||||
strncpy(msg, convertUtf8ToCurrentCodepage(msg).c_str(), std::size(msg) - 1);
|
||||
#endif
|
||||
tray.icon = TRAY_ICON;
|
||||
tray.notification_icon = TRAY_ICON;
|
||||
@@ -382,7 +382,30 @@ namespace system_tray {
|
||||
}
|
||||
|
||||
void
|
||||
update_tray_otp_pair(std::string device_name) {
|
||||
update_tray_paired(std::string device_name) {
|
||||
if (!tray_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
tray.notification_title = NULL;
|
||||
tray.notification_text = NULL;
|
||||
tray.notification_cb = NULL;
|
||||
tray.notification_icon = NULL;
|
||||
tray_update(&tray);
|
||||
char msg[256];
|
||||
snprintf(msg, std::size(msg), "Device %s paired Succesfully. Please make sure you have access to the device.", device_name.c_str());
|
||||
#ifdef _WIN32
|
||||
strncpy(msg, convertUtf8ToCurrentCodepage(msg).c_str(), std::size(msg) - 1 - 1);
|
||||
#endif
|
||||
tray.notification_title = "Device Paired Succesfully";
|
||||
tray.notification_text = msg;
|
||||
tray.notification_icon = TRAY_ICON;
|
||||
tray.tooltip = PROJECT_NAME;
|
||||
tray_update(&tray);
|
||||
}
|
||||
|
||||
void
|
||||
update_tray_client_connected(std::string client_name) {
|
||||
if (!tray_initialized) {
|
||||
return;
|
||||
}
|
||||
@@ -394,14 +417,13 @@ namespace system_tray {
|
||||
tray.icon = TRAY_ICON;
|
||||
tray_update(&tray);
|
||||
char msg[256];
|
||||
snprintf(msg, std::size(msg), "OTP Pairing started for device \"%s\". Please make sure you have access to the device initiating the pairing request.", device_name.c_str());
|
||||
snprintf(msg, std::size(msg), "%s has connected to the session.", client_name.c_str());
|
||||
#ifdef _WIN32
|
||||
strcpy(msg, convertUtf8ToCurrentCodepage(msg).c_str());
|
||||
strncpy(msg, convertUtf8ToCurrentCodepage(msg).c_str(), std::size(msg) - 1);
|
||||
#endif
|
||||
tray.icon = TRAY_ICON;
|
||||
tray.notification_title = "Incoming OTP Pairing Request";
|
||||
tray.notification_title = "Client Connected";
|
||||
tray.notification_text = msg;
|
||||
tray.notification_icon = TRAY_ICON_LOCKED;
|
||||
tray.notification_icon = TRAY_ICON;
|
||||
tray.tooltip = PROJECT_NAME;
|
||||
tray_update(&tray);
|
||||
}
|
||||
|
||||
@@ -86,5 +86,8 @@ namespace system_tray {
|
||||
update_tray_require_pin();
|
||||
|
||||
void
|
||||
update_tray_otp_pair(std::string device_name);
|
||||
update_tray_paired(std::string device_name);
|
||||
|
||||
void
|
||||
update_tray_client_connected(std::string client_name);
|
||||
} // namespace system_tray
|
||||
|
||||
Reference in New Issue
Block a user