Support subscribing for encrypted push notifications.
GitOrigin-RevId: ff0bc71f137cc0d77df4297ef22e8a885864f27b
This commit is contained in:
parent
531bf775a3
commit
bbcad65737
@ -1739,14 +1739,14 @@ localizationTargetInfo language_packs:vector<languagePackInfo> = LocalizationTar
|
|||||||
|
|
||||||
//@class DeviceToken @description Represents a data needed to subscribe for push notifications through registerDevice method. To use specific push notification service, you must specify the correct application platform and upload valid server authentication data at https://my.telegram.org
|
//@class DeviceToken @description Represents a data needed to subscribe for push notifications through registerDevice method. To use specific push notification service, you must specify the correct application platform and upload valid server authentication data at https://my.telegram.org
|
||||||
|
|
||||||
//@description A token for Google Cloud Messaging @token Device registration token; may be empty to de-register a device
|
//@description A token for Google Cloud Messaging @token Device registration token; may be empty to de-register a device @encrypt True, if push notifications should be additionally encrypted
|
||||||
deviceTokenGoogleCloudMessaging token:string = DeviceToken;
|
deviceTokenGoogleCloudMessaging token:string encrypt:Bool = DeviceToken;
|
||||||
|
|
||||||
//@description A token for Apple Push Notification service @device_token Device token; may be empty to de-register a device @is_app_sandbox True, if App Sandbox is enabled
|
//@description A token for Apple Push Notification service @device_token Device token; may be empty to de-register a device @is_app_sandbox True, if App Sandbox is enabled
|
||||||
deviceTokenApplePush device_token:string is_app_sandbox:Bool = DeviceToken;
|
deviceTokenApplePush device_token:string is_app_sandbox:Bool = DeviceToken;
|
||||||
|
|
||||||
//@description A token for Apple Push Notification service VoIP notifications @device_token Device token; may be empty to de-register a device @is_app_sandbox True, if App Sandbox is enabled
|
//@description A token for Apple Push Notification service VoIP notifications @device_token Device token; may be empty to de-register a device @is_app_sandbox True, if App Sandbox is enabled @encrypt True, if push notifications should be additionally encrypted
|
||||||
deviceTokenApplePushVoIP device_token:string is_app_sandbox:Bool = DeviceToken;
|
deviceTokenApplePushVoIP device_token:string is_app_sandbox:Bool encrypt:Bool = DeviceToken;
|
||||||
|
|
||||||
//@description A token for Windows Push Notification Services @access_token The access token that will be used to send notifications; may be empty to de-register a device
|
//@description A token for Windows Push Notification Services @access_token The access token that will be used to send notifications; may be empty to de-register a device
|
||||||
deviceTokenWindowsPush access_token:string = DeviceToken;
|
deviceTokenWindowsPush access_token:string = DeviceToken;
|
||||||
|
Binary file not shown.
@ -19,6 +19,7 @@
|
|||||||
#include "td/utils/format.h"
|
#include "td/utils/format.h"
|
||||||
#include "td/utils/JsonBuilder.h"
|
#include "td/utils/JsonBuilder.h"
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/Random.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
#include "td/utils/tl_helpers.h"
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
@ -39,11 +40,15 @@ void DeviceTokenManager::TokenInfo::store(StorerT &storer) const {
|
|||||||
STORE_FLAG(is_unregister);
|
STORE_FLAG(is_unregister);
|
||||||
STORE_FLAG(is_register);
|
STORE_FLAG(is_register);
|
||||||
STORE_FLAG(is_app_sandbox);
|
STORE_FLAG(is_app_sandbox);
|
||||||
|
STORE_FLAG(encrypt);
|
||||||
END_STORE_FLAGS();
|
END_STORE_FLAGS();
|
||||||
store(token, storer);
|
store(token, storer);
|
||||||
if (has_other_user_ids) {
|
if (has_other_user_ids) {
|
||||||
store(other_user_ids, storer);
|
store(other_user_ids, storer);
|
||||||
}
|
}
|
||||||
|
if (encrypt) {
|
||||||
|
store(encryption_key, storer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
@ -59,6 +64,7 @@ void DeviceTokenManager::TokenInfo::parse(ParserT &parser) {
|
|||||||
PARSE_FLAG(is_unregister);
|
PARSE_FLAG(is_unregister);
|
||||||
PARSE_FLAG(is_register);
|
PARSE_FLAG(is_register);
|
||||||
PARSE_FLAG(is_app_sandbox);
|
PARSE_FLAG(is_app_sandbox);
|
||||||
|
PARSE_FLAG(encrypt);
|
||||||
END_PARSE_FLAGS_GENERIC();
|
END_PARSE_FLAGS_GENERIC();
|
||||||
CHECK(is_sync + is_unregister + is_register == 1);
|
CHECK(is_sync + is_unregister + is_register == 1);
|
||||||
if (is_sync) {
|
if (is_sync) {
|
||||||
@ -72,6 +78,9 @@ void DeviceTokenManager::TokenInfo::parse(ParserT &parser) {
|
|||||||
if (has_other_user_ids) {
|
if (has_other_user_ids) {
|
||||||
parse(other_user_ids, parser);
|
parse(other_user_ids, parser);
|
||||||
}
|
}
|
||||||
|
if (encrypt) {
|
||||||
|
parse(encryption_key, parser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &string_builder, const DeviceTokenManager::TokenInfo &token_info) {
|
StringBuilder &operator<<(StringBuilder &string_builder, const DeviceTokenManager::TokenInfo &token_info) {
|
||||||
@ -95,6 +104,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DeviceTokenManage
|
|||||||
if (token_info.is_app_sandbox) {
|
if (token_info.is_app_sandbox) {
|
||||||
string_builder << ", sandboxed";
|
string_builder << ", sandboxed";
|
||||||
}
|
}
|
||||||
|
if (token_info.encrypt) {
|
||||||
|
string_builder << ", encrypted";
|
||||||
|
}
|
||||||
return string_builder;
|
return string_builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +116,7 @@ void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> devi
|
|||||||
TokenType token_type;
|
TokenType token_type;
|
||||||
string token;
|
string token;
|
||||||
bool is_app_sandbox = false;
|
bool is_app_sandbox = false;
|
||||||
|
bool encrypt = false;
|
||||||
switch (device_token_ptr->get_id()) {
|
switch (device_token_ptr->get_id()) {
|
||||||
case td_api::deviceTokenApplePush::ID: {
|
case td_api::deviceTokenApplePush::ID: {
|
||||||
auto device_token = static_cast<td_api::deviceTokenApplePush *>(device_token_ptr.get());
|
auto device_token = static_cast<td_api::deviceTokenApplePush *>(device_token_ptr.get());
|
||||||
@ -116,6 +129,7 @@ void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> devi
|
|||||||
auto device_token = static_cast<td_api::deviceTokenGoogleCloudMessaging *>(device_token_ptr.get());
|
auto device_token = static_cast<td_api::deviceTokenGoogleCloudMessaging *>(device_token_ptr.get());
|
||||||
token = std::move(device_token->token_);
|
token = std::move(device_token->token_);
|
||||||
token_type = TokenType::GCM;
|
token_type = TokenType::GCM;
|
||||||
|
encrypt = device_token->encrypt_;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case td_api::deviceTokenMicrosoftPush::ID: {
|
case td_api::deviceTokenMicrosoftPush::ID: {
|
||||||
@ -153,6 +167,7 @@ void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> devi
|
|||||||
token = std::move(device_token->device_token_);
|
token = std::move(device_token->device_token_);
|
||||||
token_type = TokenType::APNS_VOIP;
|
token_type = TokenType::APNS_VOIP;
|
||||||
is_app_sandbox = device_token->is_app_sandbox_;
|
is_app_sandbox = device_token->is_app_sandbox_;
|
||||||
|
encrypt = device_token->encrypt_;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case td_api::deviceTokenWebPush::ID: {
|
case td_api::deviceTokenWebPush::ID: {
|
||||||
@ -226,11 +241,32 @@ void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> devi
|
|||||||
}
|
}
|
||||||
info.other_user_ids = std::move(other_user_ids);
|
info.other_user_ids = std::move(other_user_ids);
|
||||||
info.is_app_sandbox = is_app_sandbox;
|
info.is_app_sandbox = is_app_sandbox;
|
||||||
|
if (encrypt != info.encrypt) {
|
||||||
|
if (encrypt) {
|
||||||
|
constexpr size_t ENCRYPTION_KEY_LENGTH = 256;
|
||||||
|
info.encryption_key.resize(ENCRYPTION_KEY_LENGTH);
|
||||||
|
Random::secure_bytes(info.encryption_key);
|
||||||
|
} else {
|
||||||
|
info.encryption_key.clear();
|
||||||
|
}
|
||||||
|
info.encrypt = encrypt;
|
||||||
|
}
|
||||||
info.promise.set_value(make_tl_object<td_api::ok>());
|
info.promise.set_value(make_tl_object<td_api::ok>());
|
||||||
info.promise = std::move(promise);
|
info.promise = std::move(promise);
|
||||||
save_info(token_type);
|
save_info(token_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<Slice> DeviceTokenManager::get_encryption_keys() const {
|
||||||
|
vector<Slice> result;
|
||||||
|
for (int32 token_type = 1; token_type < TokenType::SIZE; token_type++) {
|
||||||
|
auto &info = tokens_[token_type];
|
||||||
|
if (!info.token.empty() && info.encrypt && info.state != TokenInfo::State::Unregister) {
|
||||||
|
result.push_back(info.encryption_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
string DeviceTokenManager::get_database_key(int32 token_type) {
|
string DeviceTokenManager::get_database_key(int32 token_type) {
|
||||||
return PSTRING() << "device_token" << token_type;
|
return PSTRING() << "device_token" << token_type;
|
||||||
}
|
}
|
||||||
@ -302,7 +338,7 @@ void DeviceTokenManager::loop() {
|
|||||||
create_storer(telegram_api::account_unregisterDevice(token_type, info.token, std::move(other_user_ids))));
|
create_storer(telegram_api::account_unregisterDevice(token_type, info.token, std::move(other_user_ids))));
|
||||||
} else {
|
} else {
|
||||||
net_query = G()->net_query_creator().create(create_storer(telegram_api::account_registerDevice(
|
net_query = G()->net_query_creator().create(create_storer(telegram_api::account_registerDevice(
|
||||||
token_type, info.token, info.is_app_sandbox, BufferSlice(), std::move(other_user_ids))));
|
token_type, info.token, info.is_app_sandbox, BufferSlice(info.encryption_key), std::move(other_user_ids))));
|
||||||
}
|
}
|
||||||
info.net_query_id = net_query->id();
|
info.net_query_id = net_query->id();
|
||||||
G()->net_query_dispatcher().dispatch_with_callback(std::move(net_query), actor_shared(this, token_type));
|
G()->net_query_dispatcher().dispatch_with_callback(std::move(net_query), actor_shared(this, token_type));
|
||||||
@ -329,7 +365,7 @@ void DeviceTokenManager::on_result(NetQueryPtr net_query) {
|
|||||||
info.promise.set_value(make_tl_object<td_api::ok>());
|
info.promise.set_value(make_tl_object<td_api::ok>());
|
||||||
}
|
}
|
||||||
if (info.state == TokenInfo::State::Unregister) {
|
if (info.state == TokenInfo::State::Unregister) {
|
||||||
info.token = "";
|
info.token.clear();
|
||||||
}
|
}
|
||||||
info.state = TokenInfo::State::Sync;
|
info.state = TokenInfo::State::Sync;
|
||||||
} else {
|
} else {
|
||||||
@ -344,7 +380,7 @@ void DeviceTokenManager::on_result(NetQueryPtr net_query) {
|
|||||||
info.state = TokenInfo::State::Unregister;
|
info.state = TokenInfo::State::Unregister;
|
||||||
} else {
|
} else {
|
||||||
info.state = TokenInfo::State::Sync;
|
info.state = TokenInfo::State::Sync;
|
||||||
info.token = "";
|
info.token.clear();
|
||||||
}
|
}
|
||||||
if (r_flag.is_error()) {
|
if (r_flag.is_error()) {
|
||||||
LOG(ERROR) << r_flag.error();
|
LOG(ERROR) << r_flag.error();
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/Slice.h"
|
||||||
#include "td/utils/StringBuilder.h"
|
#include "td/utils/StringBuilder.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
@ -27,6 +28,8 @@ class DeviceTokenManager : public NetQueryCallback {
|
|||||||
void register_device(tl_object_ptr<td_api::DeviceToken> device_token_ptr, vector<int32> other_user_ids,
|
void register_device(tl_object_ptr<td_api::DeviceToken> device_token_ptr, vector<int32> other_user_ids,
|
||||||
Promise<tl_object_ptr<td_api::ok>> promise);
|
Promise<tl_object_ptr<td_api::ok>> promise);
|
||||||
|
|
||||||
|
vector<Slice> get_encryption_keys() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t MAX_OTHER_USER_IDS = 100;
|
static constexpr size_t MAX_OTHER_USER_IDS = 100;
|
||||||
|
|
||||||
@ -53,6 +56,8 @@ class DeviceTokenManager : public NetQueryCallback {
|
|||||||
uint64 net_query_id = 0;
|
uint64 net_query_id = 0;
|
||||||
vector<int32> other_user_ids;
|
vector<int32> other_user_ids;
|
||||||
bool is_app_sandbox = false;
|
bool is_app_sandbox = false;
|
||||||
|
bool encrypt = false;
|
||||||
|
string encryption_key;
|
||||||
Promise<tl_object_ptr<td_api::ok>> promise;
|
Promise<tl_object_ptr<td_api::ok>> promise;
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
|
@ -9,11 +9,13 @@
|
|||||||
#include "td/telegram/AuthManager.h"
|
#include "td/telegram/AuthManager.h"
|
||||||
#include "td/telegram/ConfigShared.h"
|
#include "td/telegram/ConfigShared.h"
|
||||||
#include "td/telegram/ContactsManager.h"
|
#include "td/telegram/ContactsManager.h"
|
||||||
|
#include "td/telegram/DeviceTokenManager.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/MessagesManager.h"
|
#include "td/telegram/MessagesManager.h"
|
||||||
#include "td/telegram/Td.h"
|
#include "td/telegram/Td.h"
|
||||||
#include "td/telegram/TdDb.h"
|
#include "td/telegram/TdDb.h"
|
||||||
|
|
||||||
|
#include "td/utils/format.h"
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
#include "td/utils/Slice.h"
|
#include "td/utils/Slice.h"
|
||||||
@ -1869,7 +1871,19 @@ void NotificationManager::on_notification_default_delay_changed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::process_push_notification(const string &payload, Promise<Unit> &&promise) {
|
void NotificationManager::process_push_notification(const string &payload, Promise<Unit> &&promise) {
|
||||||
VLOG(notifications) << "Process push notification \"" << payload << '"';
|
if (G()->close_flag()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto encryption_keys = td_->device_token_manager_->get_actor_unsafe()->get_encryption_keys();
|
||||||
|
for (auto &key : encryption_keys) {
|
||||||
|
VLOG(notifications) << "Have key \"" << format::escaped(key) << '"';
|
||||||
|
}
|
||||||
|
if (encryption_keys.empty()) {
|
||||||
|
VLOG(notifications) << "Process push notification \"" << payload << '"';
|
||||||
|
} else {
|
||||||
|
VLOG(notifications) << "Process encrypted push notification \"" << format::escaped(payload) << '"';
|
||||||
|
}
|
||||||
promise.set_value(Unit());
|
promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1367,6 +1367,9 @@ class CliClient final : public Actor {
|
|||||||
} else if (op == "rdb") {
|
} else if (op == "rdb") {
|
||||||
send_request(make_tl_object<td_api::registerDevice>(make_tl_object<td_api::deviceTokenBlackBerryPush>(args),
|
send_request(make_tl_object<td_api::registerDevice>(make_tl_object<td_api::deviceTokenBlackBerryPush>(args),
|
||||||
as_user_ids("")));
|
as_user_ids("")));
|
||||||
|
} else if (op == "rdg") {
|
||||||
|
send_request(make_tl_object<td_api::registerDevice>(
|
||||||
|
make_tl_object<td_api::deviceTokenGoogleCloudMessaging>(args, true), as_user_ids("")));
|
||||||
} else if (op == "rdt") {
|
} else if (op == "rdt") {
|
||||||
string token;
|
string token;
|
||||||
string other_user_ids_str;
|
string other_user_ids_str;
|
||||||
|
Reference in New Issue
Block a user