user_profile: add pro auto-renewing status (config key A) - #121
Open
jagerman wants to merge 1 commit into
Open
Conversation
Clients sometimes need to know whether a Pro subscription is terminal or auto-renewing (e.g. "renews on X" vs "expires on X"). Store the backend's `auto_renewing` (from get_pro_status) as a presence-only config flag `A`: 1 when auto-renewing, absent otherwise (terminal / unknown / not Pro). Deliberately not tri-state: unlike blinded_msgreqs `M`, this is backend- derived fact, not a defaulted client preference, so there's no upgrade- default edge case that a distinct "unset" would guard. And no t/T bump -- it's synced pro state like E/I/R, not a user-initiated profile edit. Exposes get_/set_pro_auto_renewing (C++ bool; C 0/1) with unit + C-API coverage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mpretty-cyro
added a commit
to mpretty-cyro/libsession-util
that referenced
this pull request
Aug 10, 2026
Completes the config side of session-foundation#121 against the Pro status-refresh spec, which asks for both `auto_renewing` and `grace` to be synced alongside `E`. session-foundation#121 ships `auto_renewing`; this adds the grace period. The backend folds the grace period into the stored expiry for auto-renewing subscriptions (`payment_expiry_at = expiry_at + grace if auto_renewing`) and sends that verbatim as `get_pro_status.expiry_ts`, so `E` is the end of coverage rather than the date a renewal is due. With `G` synced, any device recovers the paid-through instant as `E - G`; without it a config-only consumer cannot compute it at all. Not presence-checked, unlike `A`: the backend sends 0 whenever the subscription isn't auto-renewing, so an absent key and a stored zero describe the same account and both give `E - 0 == E`. There is no state a caller could act on differently. Clearing `E` clears `G` with it. A grace that outlived its expiry would pair with whatever wrote `E` next, and `set_pro_access_expiry` already clears `I` and `R` as side effects, so this follows the existing shape.
mpretty-cyro
added a commit
to mpretty-cyro/libsession-util
that referenced
this pull request
Aug 10, 2026
`set_pro_access_expiry(nullopt)` already clears `G` -- a grace is only meaningful as `E - G`, so it must not outlive its expiry. `A` has the same relationship and was not being cleared: a renewing flag with no expiry beside it describes a subscription that is not there. Every caller that clears `E` is handling an account with no entitlement -- a proof cleared, a proof revoked, or a non-positive `expiry_ts` -- and none of those is auto-renewing, so there is no state in which the flag should survive its expiry. Without this the three keys are coherent only because every *consumer* happens to test `E` before reading `A`. That is true today on all three clients and nothing enforces it; a new consumer inherits the obligation without knowing it has one. Maintaining the invariant on the write side is what removes that. Note this changes the lifecycle of `A`, which is session-foundation#121's key rather than mine -- raised deliberately as its own commit so it can be taken or dropped independently of the `G` work it sits beside.
This was referenced Aug 10, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Clients sometimes need to know whether a Pro subscription is terminal or auto-renewing (e.g. "renews on X" vs "expires on X"). Store the backend's
auto_renewing(from get_pro_status) as a presence-only config flagA: 1 when auto-renewing, absent otherwise (terminal / unknown / not Pro).Deliberately not tri-state: unlike blinded_msgreqs
M, this is backend- derived fact, not a defaulted client preference, so there's no upgrade- default edge case that a distinct "unset" would guard. And no t/T bump -- it's synced pro state like E/I/R, not a user-initiated profile edit.Exposes get_/set_pro_auto_renewing (C++ bool; C 0/1) with unit + C-API coverage.