From d220c9a1aa80c67c85e43df2bf86264e8a400443 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Tue, 18 Nov 2025 16:49:11 +1100 Subject: [PATCH 1/2] fix: use extradata for proconfig & features --- include/pro/pro.hpp | 6 +-- include/pro/types.hpp | 5 +-- include/user_config.hpp | 9 ++-- libsession-util | 2 +- src/constants.cpp | 24 +++++----- src/encrypt_decrypt/encrypt_decrypt.cpp | 3 -- src/pro/pro.cpp | 10 ++--- src/user_config.cpp | 59 ++++++++++++------------- types/multi_encrypt/multi_encrypt.d.ts | 14 ++---- types/pro/pro.d.ts | 7 ++- types/user/userconfig.d.ts | 13 ++++-- 11 files changed, 72 insertions(+), 80 deletions(-) diff --git a/include/pro/pro.hpp b/include/pro/pro.hpp index 995e1ef..4ab3dfd 100644 --- a/include/pro/pro.hpp +++ b/include/pro/pro.hpp @@ -20,7 +20,7 @@ std::string_view proBackendEnumToString(SESSION_PRO_BACKEND_PAYMENT_PROVIDER v); std::string_view proBackendEnumToString(SESSION_PRO_BACKEND_PAYMENT_STATUS v); std::string_view proBackendEnumToString(SESSION_PRO_BACKEND_PLAN v); std::string_view proBackendEnumToString(SESSION_PRO_BACKEND_USER_PRO_STATUS v); -std::string_view proBackendEnumToString(SESSION_PRO_BACKEND_GET_PRO_STATUS_ERROR_REPORT v); +std::string_view proBackendEnumToString(SESSION_PRO_BACKEND_GET_PRO_DETAILS_ERROR_REPORT v); std::string_view proBackendEnumToString(session::ProFeaturesForMsgStatus v); template @@ -193,7 +193,7 @@ class ProWrapper : public Napi::ObjectWrap { auto master_privkey_decoded = from_hex(master_privkey); auto rotating_privkey_decoded = from_hex(rotating_privkey); - std::string json = pro_backend::GetProProofRequest::build_to_json( + std::string json = pro_backend::GenerateProProofRequest::build_to_json( static_cast(requestVersion.Int32Value()), to_span(master_privkey_decoded), to_span(rotating_privkey_decoded), @@ -267,7 +267,7 @@ class ProWrapper : public Napi::ObjectWrap { auto master_privkey_decoded = from_hex(master_privkey); - auto json = pro_backend::GetProStatusRequest::build_to_json( + auto json = pro_backend::GetProDetailsRequest::build_to_json( static_cast(requestVersion.Int32Value()), to_span(master_privkey_decoded), unix_ts_ms, diff --git a/include/pro/types.hpp b/include/pro/types.hpp index e5d4091..4ddede2 100644 --- a/include/pro/types.hpp +++ b/include/pro/types.hpp @@ -44,8 +44,6 @@ struct toJs_impl { obj["timestampMs"] = toJs(env, envelope.timestamp.count()); obj["source"] = envelope.source.size() ? toJs(env, envelope.source) : env.Null(); - obj["proSigHex"] = - envelope.pro_sig.size() ? toJs(env, oxenc::to_hex(envelope.pro_sig)) : env.Null(); return obj; } @@ -75,8 +73,7 @@ struct toJs_impl { toJs(env, decoded_pro.status == ProStatus::InvalidProBackendSig ? "InvalidProBackendSig" : decoded_pro.status == ProStatus::InvalidUserSig ? "InvalidUserSig" - : decoded_pro.status == ProStatus::Valid ? "Valid" - : "Expired"); + : "Valid"); obj["proProof"] = toJs(env, decoded_pro.proof); obj["proFeaturesBitset"] = proFeaturesToJsBitset(env, decoded_pro.features); diff --git a/include/user_config.hpp b/include/user_config.hpp index c61bdb3..7ae20c1 100644 --- a/include/user_config.hpp +++ b/include/user_config.hpp @@ -16,10 +16,6 @@ class UserConfigWrapper : public ConfigBaseImpl, public Napi::ObjectWrap pro_config; - int64_t pro_user_features = 0; - config::UserProfile& config{get_config()}; Napi::Value getPriority(const Napi::CallbackInfo& info); @@ -42,8 +38,11 @@ class UserConfigWrapper : public ConfigBaseImpl, public Napi::ObjectWrap -#include - #include "base_config.hpp" -#include "oxen/log.hpp" #include "oxenc/hex.h" #include "pro/types.hpp" #include "profile_pic.hpp" -#include "session/config/base.hpp" #include "session/config/user_profile.hpp" #include "session/ed25519.hpp" #include "utilities.hpp" @@ -107,8 +103,9 @@ void UserConfigWrapper::Init(Napi::Env env, Napi::Object exports) { InstanceMethod("setNoteToSelfExpiry", &UserConfigWrapper::setNoteToSelfExpiry), InstanceMethod("getProConfig", &UserConfigWrapper::getProConfig), InstanceMethod("setProConfig", &UserConfigWrapper::setProConfig), - InstanceMethod( - "setProFeaturesBitset", &UserConfigWrapper::setProFeaturesBitset), + InstanceMethod("removeProConfig", &UserConfigWrapper::removeProConfig), + InstanceMethod("setProBadge", &UserConfigWrapper::setProBadge), + InstanceMethod("setAnimatedAvatar", &UserConfigWrapper::setAnimatedAvatar), InstanceMethod( "getProFeaturesBitset", &UserConfigWrapper::getProFeaturesBitset), InstanceMethod( @@ -266,11 +263,8 @@ void UserConfigWrapper::setNoteToSelfExpiry(const Napi::CallbackInfo& info) { Napi::Value UserConfigWrapper::getProConfig(const Napi::CallbackInfo& info) { return wrapResult(info, [&] { - // TODO fixme once extra_data is implemented - - oxen::log::warning(cat, "getProConfig() is not wrapped to libsession"); - if (this->pro_config.has_value()) { - return toJs(info.Env(), this->pro_config); + if (config.get_pro_config().has_value()) { + return toJs(info.Env(), config.get_pro_config().value()); } return info.Env().Null(); @@ -285,38 +279,43 @@ void UserConfigWrapper::setProConfig(const Napi::CallbackInfo& info) { session::config::ProConfig pro_config = pro_config_from_object(pro_config_js.As()); - // TODO fixme once extra_data is implemented - // config.set_pro_config(pro_config); - this->pro_config = pro_config; + config.set_pro_config(pro_config); }); } -Napi::Value UserConfigWrapper::getProFeaturesBitset(const Napi::CallbackInfo& info) { +Napi::Value UserConfigWrapper::removeProConfig(const Napi::CallbackInfo& info) { return wrapResult(info, [&] { - // TODO fixme once extra_data is implemented - // config.get_pro_features_bitset(); - oxen::log::warning(cat, "getProFeaturesBitset() is not wrapped to libsession"); - return proFeaturesToJsBitset(info.Env(), this->pro_user_features); + assertInfoLength(info, 0); + + return config.remove_pro_config(); }); } -void UserConfigWrapper::setProFeaturesBitset(const Napi::CallbackInfo& info) { +Napi::Value UserConfigWrapper::getProFeaturesBitset(const Napi::CallbackInfo& info) { + return wrapResult( + info, [&] { return proFeaturesToJsBitset(info.Env(), config.get_pro_features()); }); +} + +void UserConfigWrapper::setProBadge(const Napi::CallbackInfo& info) { wrapExceptions(info, [&] { assertInfoLength(info, 1); - auto pro_features = info[0]; - assertIsObject(info[0]); - auto obj = info[0].As(); - assertIsBigint(obj.Get("proFeaturesBitset"), "UserConfigWrapper::setProFeaturesBitset"); + assertIsBoolean(info[0], "setProBadge"); + + auto enabled = toCppBoolean(info[0], "UserConfigWrapper::setProBadge"); - auto pro_user_features_js = obj.Get("proFeaturesBitset"); - auto pro_user_features_cpp = toCppIntegerB( - pro_user_features_js, "UserConfigWrapper::setProFeaturesBitset", false); + config.set_pro_badge(enabled); + }); +} + +void UserConfigWrapper::setAnimatedAvatar(const Napi::CallbackInfo& info) { + wrapExceptions(info, [&] { + assertInfoLength(info, 1); + assertIsBoolean(info[0], "setAnimatedAvatar"); - // TODO fixme once extra_data is implemented + auto enabled = toCppBoolean(info[0], "UserConfigWrapper::setAnimatedAvatar"); - // config.set_pro_features_bitset(pro_user_features_cpp); - this->pro_user_features = pro_user_features_cpp; + config.set_animated_avatar(enabled); }); } diff --git a/types/multi_encrypt/multi_encrypt.d.ts b/types/multi_encrypt/multi_encrypt.d.ts index aa791cb..add4909 100644 --- a/types/multi_encrypt/multi_encrypt.d.ts +++ b/types/multi_encrypt/multi_encrypt.d.ts @@ -61,12 +61,6 @@ declare module 'libsession_util_nodejs' { type WithDecodedPro = { decodedPro: DecodedPro | null; }; - type WithProSigHex = { - /** - * HexString - */ - proSigHex: string | null; - }; type Envelope = { timestampMs: number; @@ -74,13 +68,13 @@ declare module 'libsession_util_nodejs' { * HexString, 33 bytes, 66 chars */ source: string | null; - /** - * HexString - */ - proSigHex: string | null; }; type WithEnvelope = { + /** + * The envelope payload, if present. For communities, the envelope is not currently included, but will eventually be. + * We want to support both cases, hence why we use this type for decryptForCommunity, instead of WithNonNullableEnvelope + */ envelope: Envelope | null; }; diff --git a/types/pro/pro.d.ts b/types/pro/pro.d.ts index 46b9627..41550e7 100644 --- a/types/pro/pro.d.ts +++ b/types/pro/pro.d.ts @@ -10,7 +10,7 @@ declare module 'libsession_util_nodejs' { proBackendPubkeyHex: string; }; - type ProStatus = 'InvalidProBackendSig' | 'InvalidUserSig' | 'Valid' | 'Expired'; + type ProStatus = 'InvalidProBackendSig' | 'InvalidUserSig' | 'Valid'; type WithProFeaturesBitset = { proFeaturesBitset: bigint }; type WithGenIndexHash = { genIndexHashB64: string }; @@ -42,7 +42,6 @@ declare module 'libsession_util_nodejs' { rotatingPrivKeyHex: string; }; - type ProConfig = WithRotatingPrivKeyHex & { proProof: ProProof; }; @@ -55,8 +54,8 @@ declare module 'libsession_util_nodejs' { store_other: string; platform: string; platform_account: string; - refund_url: string; - refund_after_platform_deadline_url: string; + refund_support_url: string; + refund_platform_url: string; update_subscription_url: string; cancel_subscription_url: string; }; diff --git a/types/user/userconfig.d.ts b/types/user/userconfig.d.ts index 3cfbd40..786bc35 100644 --- a/types/user/userconfig.d.ts +++ b/types/user/userconfig.d.ts @@ -40,8 +40,10 @@ declare module 'libsession_util_nodejs' { setProConfig: (proConfig: ProConfig) => void; getProConfig: () => ProConfig | null; + removeProConfig: () => boolean; - setProFeaturesBitset: (args: WithProFeaturesBitset) => void; + setAnimatedAvatar: (enabled: boolean) => void; + setProBadge: (enabled: boolean) => void; /** * * @returns 0 if no pro user features are enabled, the bitset of pro features enabled otherwise @@ -91,8 +93,11 @@ declare module 'libsession_util_nodejs' { public setNoteToSelfExpiry: UserConfigWrapper['setNoteToSelfExpiry']; public getProConfig: UserConfigWrapper['getProConfig']; public setProConfig: UserConfigWrapper['setProConfig']; + public removeProConfig: UserConfigWrapper['removeProConfig']; public getProFeaturesBitset: UserConfigWrapper['getProFeaturesBitset']; - public setProFeaturesBitset: UserConfigWrapper['setProFeaturesBitset']; + public setAnimatedAvatar: UserConfigWrapper['setAnimatedAvatar']; + public setProBadge: UserConfigWrapper['setProBadge']; + public generateProMasterKey: UserConfigWrapper['generateProMasterKey']; public generateRotatingPrivKeyHex: UserConfigWrapper['generateRotatingPrivKeyHex']; } @@ -120,8 +125,10 @@ declare module 'libsession_util_nodejs' { | MakeActionCall | MakeActionCall | MakeActionCall + | MakeActionCall | MakeActionCall - | MakeActionCall + | MakeActionCall + | MakeActionCall | MakeActionCall | MakeActionCall; } From 03f96de68b64677052dbb7c5b1f9ab3a86767b65 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Tue, 18 Nov 2025 17:14:18 +1100 Subject: [PATCH 2/2] chore: lint --- include/utilities.hpp | 18 +++++++++--------- src/encrypt_decrypt/encrypt_decrypt.cpp | 15 ++++++--------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/include/utilities.hpp b/include/utilities.hpp index c04a3a4..0973b11 100644 --- a/include/utilities.hpp +++ b/include/utilities.hpp @@ -413,11 +413,10 @@ template std::array from_hex_to_array(std::string x) { std::string as_hex = oxenc::from_hex(x); if (as_hex.size() != N) { - throw std::invalid_argument( - fmt::format( - "from_hex_to_array: Decoded hex size mismatch: expected {}, got {}", - N, - as_hex.size())); + throw std::invalid_argument(fmt::format( + "from_hex_to_array: Decoded hex size mismatch: expected {}, got {}", + N, + as_hex.size())); } std::array result; @@ -433,15 +432,16 @@ std::vector from_base64_to_vector(std::string_view x); // Concept to match containers with a size() method template concept HasSize = requires(T t) { - {t.size()}->std::convertible_to; + { + t.size() + } -> std::convertible_to; }; template void assert_length(const T& x, size_t n, std::string_view base_identifier) { if (x.size() != n) { - throw std::invalid_argument( - fmt::format( - "assert_length: expected {}, got {} for {}", n, x.size(), base_identifier)); + throw std::invalid_argument(fmt::format( + "assert_length: expected {}, got {} for {}", n, x.size(), base_identifier)); } } diff --git a/src/encrypt_decrypt/encrypt_decrypt.cpp b/src/encrypt_decrypt/encrypt_decrypt.cpp index 3e286b7..72c64bc 100644 --- a/src/encrypt_decrypt/encrypt_decrypt.cpp +++ b/src/encrypt_decrypt/encrypt_decrypt.cpp @@ -636,9 +636,8 @@ Napi::Value MultiEncryptWrapper::decryptForCommunity(const Napi::CallbackInfo& i auto contentOrEnvelope = extractContentOrEnvelope(obj, "decryptForCommunity.obj.contentOrEnvelope"); - decrypted.push_back( - session::decode_for_community( - contentOrEnvelope, nowMs, proBackendPubkeyHex)); + decrypted.push_back(session::decode_for_community( + contentOrEnvelope, nowMs, proBackendPubkeyHex)); decryptedServerIds.push_back(serverId); } catch (const std::exception& e) { @@ -728,9 +727,8 @@ Napi::Value MultiEncryptWrapper::decryptFor1o1(const Napi::CallbackInfo& info) { auto envelopePayload = extractEnvelopePayload(obj, "decryptFor1o1.obj.envelopePayload"); - decrypted.push_back( - session::decode_envelope( - keys, envelopePayload, nowMs, proBackendPubkeyHex)); + decrypted.push_back(session::decode_envelope( + keys, envelopePayload, nowMs, proBackendPubkeyHex)); decryptedMessageHashes.push_back(messageHash); } catch (const std::exception& e) { log::warning( @@ -832,9 +830,8 @@ Napi::Value MultiEncryptWrapper::decryptForGroup(const Napi::CallbackInfo& info) auto envelopePayload = extractEnvelopePayload(obj, "decryptForGroup.obj.envelopePayload"); - decrypted.push_back( - session::decode_envelope( - keys, envelopePayload, nowMs, proBackendPubkeyHex)); + decrypted.push_back(session::decode_envelope( + keys, envelopePayload, nowMs, proBackendPubkeyHex)); decryptedMessageHashes.push_back(messageHash); } catch (const std::exception& e) { log::warning(