Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions library/src/main/cpp/pro_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <oxenc/hex.h>
#include <session/pro_backend.hpp>
#include <session/session_protocol.h>

#include "jni_utils.h"
#include "util.h"
Expand Down Expand Up @@ -60,6 +61,28 @@ JavaLocalRef<jobject> serialize_provider_urls(JNIEnv* env, const pb::ProviderURL
jstring_from_optional(env, u.cancel_subscription_url).get())};
}

/// The Pro URL registry as one Kotlin object. Reads `SESSION_PROTOCOL_STRINGS` directly - it is
/// declared `extern const` in the public C header, so no C++ surface had to be added for this.
///
/// Field order MUST match `ProUrls`'s constructor. The two document urls are the `url_pro_*` ones:
/// the registry also carries generic `url_privacy_policy` / `url_terms_of_service`, which are
/// different pages and do not belong on a Pro object.
JavaLocalRef<jobject> serialize_pro_urls(JNIEnv* env) {
static BasicJavaClassInfo cls(env, "network/loki/messenger/libsession_util/pro/ProUrls",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
const auto& s = SESSION_PROTOCOL_STRINGS;
return {env, env->NewObject(cls.java_class, cls.constructor,
jstring_from_optional(env, std::string_view(s.url_pro_access_not_found)).get(),
jstring_from_optional(env, std::string_view(s.url_pro_faq)).get(),
jstring_from_optional(env, std::string_view(s.url_pro_page)).get(),
jstring_from_optional(env, std::string_view(s.url_pro_privacy_policy)).get(),
jstring_from_optional(env, std::string_view(s.url_pro_roadmap)).get(),
jstring_from_optional(env, std::string_view(s.url_pro_support)).get(),
jstring_from_optional(env, std::string_view(s.url_pro_terms_of_service)).get(),
jstring_from_optional(env, std::string_view(s.url_pro_upgrade)).get())};
}

// §1: `plan` is a parsed ProPlanPeriod (count + unit). We hand the app the structured pair —
// count as an int, unit as a lowercase name — so nothing downstream has to re-parse a slug (matching
// the nodejs glue's {planCount, planUnit}). The unit is preserved exactly, never canonicalized.
Expand Down Expand Up @@ -249,6 +272,14 @@ Java_network_loki_messenger_libsession_1util_pro_BackendRequests_providerUrls(
});
}

extern "C"
JNIEXPORT jobject JNICALL
Java_network_loki_messenger_libsession_1util_pro_BackendRequests_proUrls(JNIEnv* env, jobject) {
return run_catching_cxx_exception_or_throws<jobject>(env, [=]() -> jobject {
return serialize_pro_urls(env).release();
});
}

// --- Backend identity constants (single source of truth in libsession) ---

extern "C"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ object BackendRequests : LibSessionUtilCApi() {

external fun providerUrls(providerCode: String): ProviderUrls?

/**
* The Pro URL registry. Identical for every user and owned by libsession, so read this rather than
* copying the values — a client-side copy of a libsession constant is a value that can silently
* drift from the one the other clients use.
*/
external fun proUrls(): ProUrls

/**
* The purchasable payment-provider slugs to surface to users (single source of truth in libsession;
* excludes non-purchasable providers like `stf`). Order is not significant — the client
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,27 @@ data class ProRequest(
val body: String,
)

/**
* The Pro URL registry — the `url_pro_*` fields of libsession's `SESSION_PROTOCOL_STRINGS`.
*
* Not per-provider and not translation data: these are identical for every user, which is why
* libsession owns them. Exposed as one object rather than eight calls, matching [ProviderUrls].
*
* Note [privacyPolicy] and [termsOfService] are the **Pro** documents (`url_pro_*`), not Session's
* general ones — the registry carries both pairs and they are different pages.
*/
@Keep
data class ProUrls(
val accessNotFound: String,
val faq: String,
val page: String,
val privacyPolicy: String,
val roadmap: String,
val support: String,
val termsOfService: String,
val upgrade: String,
)

/** Per-provider support/management URLs — libsession is the source of truth for these. */
@Keep
data class ProviderUrls(
Expand Down
Loading