Commit Graph
1705 Commits
Author SHA1 Message Date
spacedandy-agents-simplex e051b50323 core: alert a subscriber that a payment failed, a renewal nears, or it was cancelled or ended
A subscription's alerts were the prepaid ones: a retired subscription said
"support ended", and nothing told the user a payment failed, an annual
renewal was near, or a cancelled subscription still runs. The derived alert
for a subscription is now, in order: subscription_ended once retired,
payment_issue while the store retries, issue_failed as before,
subscription_cancelled before paidThrough, and renewal_approaching from
three days before an annual plan renews, with a wake at that moment. Monthly
plans get no reminder, as there is no opt-out yet.

The unreleased migration's down step clears an acked subscription_cancelled,
which an older core cannot read.

Run: 003-badge-subscriptions-ui, slice 7
2026-10-15 06:38:03 +00:00
spacedandy-agents-simplex a3b2e5c9f1 core: refuse a badge code or invoice while a store receipt is pending
A code redeemed while a store receipt is held put the code's badge on the
profile, and the held receipt then waited behind it; for a subscription the
store kept charging every period meanwhile. Code redemption and invoice
creation now answer "store purchase open" while the profile holds an App
Store subscription receipt, or another receipt whose last failure can clear
on its own. A receipt that failed for good does not block, except an Apple
subscription, which Apple keeps charging; an uncredited Play subscription is
refunded by Play.

Run: 003-badge-subscriptions-ui, slice 6
2026-10-15 06:11:10 +00:00
spacedandy-agents-simplex 664e5388ff core: let a held App Store subscription adopt its later transactions
A held Apple subscription record is keyed by its original transaction id,
so every renewal resolves to it. It kept the payment's back-off when a new
transaction arrived, and adopted any payment handed over, including a
revoked renewal, which the service refuses as receipt_invalid and so would
refuse the whole subscription.

A held Apple record now adopts a JWS only for another transaction with a
later purchaseDate and no revocationDate, read from the unverified payload,
and is then due at once with its retry delay and credit error cleared. A
re-delivered or re-signed copy changes nothing. A failed attempt writes its
back-off only if the record still holds the payment it sent.

Run: 003-badge-subscriptions-ui, slice 5
2026-10-15 03:42:23 +00:00
spacedandy-agents-simplex c91df49dad core: claim a store-listed transaction only on the device that bought it
A store account's purchases are listed on every device signed into it:
Play's purchase query lists active subscriptions for their whole life, and
Apple's Transaction.updates delivers auto-renewables made on other devices.
A hand-over with no record and an unknown echoed invoice made a new record
under the presenting profile, so another device could claim a buyer's
subscription for its own active profile, or repeat a refused request every
30 days after cleanup.

/_badge purchase now takes a `listed` mark, which the apps' sweeps and
purchase listeners send: it joins only a record this core already has for
the transaction or its echoed invoice, and otherwise records and sends
nothing (CRStoreReceiptNotRecorded). The purchase call and Restore hand over
unmarked, as before.

Run: 003-badge-subscriptions-ui, slice 4
2026-10-15 00:53:16 +00:00
spacedandy-agents-simplex f126ef075d core: record the device store's view of a subscription
The service reads the store only once a subscription's paid coverage has
ended, so it never sees a cancellation while the period runs. The apps read
the device's store (StoreKit's renewal state, Play's isAutoRenewing) and
report it with /_badge subscription <state> <payment>, which records it on
the credited subscription purchase the payment resolves to and announces the
change to its owner.

A renewing report does not replace billingRetry or ended: Play lists a
subscription in its grace period with auto-renew on, and the service's next
answer clears billing retry once the charge lands.

Run: 003-badge-subscriptions-ui, slice 3
2026-10-14 23:00:34 +00:00
spacedandy-agents-simplex 7bc4dbca36 core: keep a store subscription's state on the client
The screens and alerts need to know whether a subscription renews, was
cancelled, waits for a charge, or ended, and the client dropped every state
the service sent but ended. It is now stored on the purchase: from the
answer to the first credit, and from a renewal answer only when the
asserted tip's coverage had ended, since while coverage runs the service
repeats what it read at the last renewal (a year old for an annual plan).

BadgeState gains `subscription` (the plan's months, from the latest charge
credit, and the state), and fills renewsAt/willRenew from it. A changed
state is announced with CEvtBadgeChanged. The column goes into the
unreleased M20260925 migration.

Run: 003-badge-subscriptions-ui, slice 2
2026-10-14 20:27:40 +00:00
spacedandy-agents-simplex a488fbc4d2 core: move SubscriptionState to Badges.Types (structural)
BadgeState, which lives in Badges.Types, is about to carry a subscription's
state, and Badges.Service imports Badges.Types. Service re-exports it, as it
does BadgeServiceErrorCode. No behaviour change.

Run: 003-badge-subscriptions-ui, slice 1
2026-10-14 18:06:13 +00:00
spacedandy-agents-simplex f1fe4e6706 core: update query plans
getBadgePurchase derives the purchase kind from the ledger replica, and a
subscription test makes a held store receipt due.

Run: 001-badge-subscriptions, final verification
2026-10-14 10:17:40 +00:00
spacedandy-agents-simplex 8087e3804e core: keep a subscription badge until the service says it ended
A purchase is a subscription exactly when its ledger replica holds a
charge credit, so the kind is derived with no column or migration. A
subscription is still asked about at zero months, at the shared weekly
moment, and keeps its badge past paidThrough until an answer says the
subscription ended, so a renewed month is presented at the old
credential's expiry with no gap, and a charge the store recovers later
still re-activates it. While it waits, the client records no failure and
raises no support-ended alert; "issued no credential" now fires only while
the ledger still owes a month. Prepaid purchases are unchanged.

Run: 001-badge-subscriptions, slice 5
2026-10-14 05:36:33 +00:00
spacedandy-agents-simplex 648aee4cea core, badge-service: plan subscription charges and claim Apple subscriptions by original id
Add chargeEntries, the one planner for a store charge's ledger rows: a
lapse to the billing period start, the grant dated to that start, and a
lapse to now, so coverage follows the store's periods and every row
verifies by re-running it at its createdAt. A test runs its rows through
the client's own balanceChecked for first charges, monthly and annual
renewals, billing-retry recovery and grace.

An Apple auto-renewable transaction is now claimed by its original
transaction id, which every renewal keeps, so renewals resolve to one
purchase. One function names the ref for both the claim and the real
verifier, so they cannot disagree.

Run: 001-badge-subscriptions, slice 3a
2026-10-14 02:35:51 +00:00
spacedandy-agents-simplex 85901458ec core, badge-service: store subscription charges and carry the subscription state
Add the service migration 20261012_badge_subscriptions: the subscription
charges table, the ledger's charge_id, and the payment's subscription state,
check time and Play token, replacing three subscription columns nothing
wrote. The ledger now stores and reads back charge credits, and the badge
credential response gains an optional subscription state that older clients
ignore and that reads an unknown state without failing. Nothing writes a
charge or a state yet, so no behaviour changes.

Run: 001-badge-subscriptions, slice 2
2026-10-13 22:45:10 +00:00
spacedandy-agents-simplex dcbf3ee262 core, badge-service: name Apple claims by reference
Rename appleTransactionId to appleTransactionRef, matching googlePurchaseRef
and StoreTransactionRef. No behaviour change: the next change makes it
return a subscription's original transaction id, which the old name would
misstate.

Run: 001-badge-subscriptions, slice 1
2026-10-13 20:56:50 +00:00
spaced4ndy 59c588932e badge-service: verify App Store and Google Play purchases (#7654) 2026-10-13 15:24:07 +00:00
spaced4ndy 5cddbffaa1 core: update query plans 2026-10-09 17:18:09 +04:00
spaced4ndy 57ab333a2b Merge branch 'master' into badge-in-app-checkout 2026-10-09 15:00:36 +04:00
EvgenyandEvgeny @ SimpleX Chat f924d233e4 core: fix encoding for name proof (#7672)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-09 07:48:04 +01:00
EvgenyandEvgeny @ SimpleX Chat f2b3fe385c core: remove legacy field to support contact connections in groups (#7671)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-09 07:00:27 +01:00
EvgenyandEvgeny @ SimpleX Chat 9c9c86f9c0 core, ui: fix profiles, add error alerts (#7663)
* core, ui: fix profiles, add error alerts

* simplify

* query plans

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-08 22:53:59 +01:00
spaced4ndy b071285d15 tests: drop store purchase tests covered by their neighbours, and pin the rules none covered (#7665) 2026-10-08 15:45:12 +00:00
EvgenyandEvgeny @ SimpleX Chat 96970373b0 core: add status when switching queue (#7664)
* core: add status when switching queue

* fix

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-08 16:31:29 +01:00
EvgenyandEvgeny @ SimpleX Chat 0c1ffa65bc core: group fixes/improvements (#7660)
* core: group fixes/improvements

* Large messages dropped by relays and hosts (the same 15602 limit was applied, without accounting for forwarding header)
* Members below v18 did not receive forwarded messages or history in p2p groups.
* Join confirmations near the size limit could fail.
* SMP servers are limited to 2 host names each.

* simplify

* remove legacy forwarding and history support

* only restrict p2p groups

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-08 15:06:18 +01:00
spaced4ndy b4f1249436 core, ios, android: name the resolved store purchase so the app finishes it without a sweep (#7659) 2026-10-08 13:46:27 +00:00
spaced4ndy 80b7f96a96 merge master into badge-in-app-checkout 2026-10-08 14:31:30 +04:00
spaced4ndy 27d12f230d core, ui: buy a badge with an App Store or Google Play purchase (#7590) 2026-10-07 14:32:48 +00:00
Evgeny Poberezkin 84f73ce8b8 website: update crowdfunding page 2026-10-07 09:53:45 +01:00
EvgenyandEvgeny @ SimpleX Chat df95de8a2c tests, fix: execute in parallel, send connected events after creating chat items, fix race when merging multiple members to one contact (#7500)
* tests: execute in parallel

* remove race in terminal

* fix some tests

* stop chat controller on exit

* fix more tests

* fix tests

* query plans

* update simplexmq

* update direct-sqlcipher

* fix tests

* query plans

* ios: update core

* fix tests

* update simplexmq and direct-sqlcipher, fixes

* simplexmq

* update simplexmq

* parallel channel tests

* update tests

* fix tests

* fix tests

* query plans

* fix test

* more tests in CI

* use ram drive in CI

* fix tests, fix directory deleting voice file before it is uploaded

* fix query

* fix query to use index

* link contact and channel owner profile when connecting via a signed link

* update simplexmq, fix ghc 8.10.7

* fix tests

* avoid double stop

* query plans

* fix more test races

* more test fixes

* fix queries

* fixes

* more fixes

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-07 08:12:02 +01:00
spaced4ndyandEvgeny Poberezkin 86671a1699 core, ui: confirm before connecting a call answered without e2e encryption (#7647)
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
2026-10-05 09:45:57 +01:00
Evgenyandshum b79223fe5c core: call media key HKDF, expire stale calls (#7642)
* core: call media key HKDF, expire stale calls

* core: expire stale calls in bulk SQL

* core: reduce call tests

* core: remove periodic call cleanup

* core: expire calls with DELETE RETURNING

* core: skip call item update when none expired

---------

Co-authored-by: shum <github.shum@liber.li>
2026-10-04 18:44:52 +01:00
1a969a6cb9 core, ui: remove database backups after key changes (#7628)
* core, ui: remove database backups after key changes

* ui: delete database backups on chat start without delaying encryption marker reset

Keeping encryptionStartedAt set until chat start made DatabaseErrorView show
"The attempt to change database passphrase was not completed" with a Restore
button after every successful passphrase change when the passphrase is not
stored. Restore the marker handling from master and delete backups
unconditionally after chat starts.

* another flag

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
Co-authored-by: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com>
2026-10-03 16:56:58 +01:00
EvgenyandEvgeny @ SimpleX Chat ffcc2258cc core: prohibit XFTP redirects in sent files (#7617)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-02 17:36:24 +01:00
spaced4ndy fbf075aa36 core: prohibit assigning owner role in channels (#7631) 2026-10-01 09:01:50 +01:00
spaced4ndy 0ef32c0bcc core: prevent moderators from accepting members with moderator role (#7629) 2026-10-01 09:00:51 +01:00
Evgeny Poberezkin 93910b80e9 core: 7.1.0.9 (simplexmq 7.1.0.10) 2026-09-30 14:09:11 +01:00
EvgenyandEvgeny @ SimpleX Chat 851ff062da core: compress messages if needed to fit envelope, even if there is no PQ e2ee in connection (#7630)
* core: compress messages if needed to fit envelope, even if there is no PQ e2ee in connection

* simplify

* remove noise

* compress messages without PQ too

* case

* update query plans

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-30 14:07:00 +01:00
EvgenyandEvgeny @ SimpleX Chat 80f8757449 core: remove .exported db files when database is removed (#7615)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-30 10:09:18 +01:00
sh b1dc25dc3e badges: service group with multi-use codes (#7578)
* core: cancel the chat callback on interrupt

* badges: add multi-use codes

* badges: add the managed group

* badges: document multi-use codes and the group

* core: sign test badges with whole-second expiry

* badges: rework tracker and reply texts
2026-09-30 08:48:57 +01:00
EvgenyandEvgeny @ SimpleX Chat be39a42121 core: limit the number of skipped keys during remote access (#7622)
* core: limit the number of skipped keys during remote access

* simplify

* core: restrict body size for XRCP commands and responses, limit decompressed size (#7616)

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-30 07:16:52 +01:00
EvgenyandEvgeny @ SimpleX Chat 8b804a4fba core: restrict body size for XRCP commands and responses, limit decompressed size (#7616)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-29 23:01:33 +01:00
EvgenyandEvgeny @ SimpleX Chat e863ee4c27 core: limit depth of forwarded messages (#7614)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-29 21:56:03 +01:00
EvgenyandEvgeny @ SimpleX Chat a12552d427 relays: remove of files with base64 padding in the name, log errors (#7611)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-29 19:22:25 +01:00
EvgenyandEvgeny @ SimpleX Chat 643a9afad6 bots: SimpleX Calculator demo bot (#7583)
* bots: SimpleX Calculator demo bot

* refactor

* use local server in test

* simplify

* icon

* simplify

* expression

* replies

* improve

* log

* update name in bot address

* @simplex-chat/type: 0.12.0

* simplex-chat nodejs: 7.1.0-beta.4.2

* update dependencies

* option to add domain to bot address

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-27 17:20:40 +01:00
Evgeny Poberezkin 7e7d699fff core: update query plans 2026-09-26 16:24:03 +01:00
EvgenyandEvgeny @ SimpleX Chat 0ef0db8ad7 core: fix races when sending and receiving files (in tests, or when server is very fast) (#7584)
* core: fix races when sending and receiving files (in tests, or when server is very fast)

* update simplexmq

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-25 15:12:31 +01:00
19e70faeec badges: webapp feature branch (#7548)
* badges: webapp (#7433)

* badges: service migrations, store and catalog

* badges: BTCPay provider and settlement poller

* badges: web listener and /api endpoints

* web: checkout single-page app

* badges: tests and BTCPay fixtures

* badges: README and ini reference

* badges: fix hex16 build on GHC 8.10.7

* badges: Stripe card lane

* badges: fix Stripe card checkout, add theming

* badges: add a discount row to the order summary

* badges: site navbar, embedding, theme, Forget move

* badges: use SB code prefix in web checkout

* badges: rename sxb app namespace to sb

* badges: embed checkout nav via site; keep original app navbar

* badges: post iframe height, apply site background when embedded

* badges: embed dark surfaces, steadier iframe height

* badges: hide app footer when embedded

* badges: size embedded body to content, not viewport

* badges: declare color-scheme to stop reload flash

* badges: fade shell in on load, no reload blank

* badges: prerender app shell into index.html

* badges: pre-paint theme, hide shell on deep reload

* badges: logo returns to landing client-side

* badges: embedded wizard back, buy-a-code, resume

* badges: signal app-managed screens, resume across reload

* badges: rebuild wizard history on deep load so Back walks it

* badges: carry welcome-page height as the iframe floor

* badges: keep selection on Buy a code; rename to Your codes

* badges: read web shell as UTF-8, not locale

* badges: resume the exact paid order after Stripe card redirect

* badges: move docker deploy under scripts

* badges: add serve_webapp toggle and webapp export

* badges: wire split webapp deploy in docker config

* badges: quiet agent logs by default

* badges: resume card redirect in the embedded frame

* badges: migrate Stripe adapter to PaymentIntents

* badges: correct Stripe restricted key scopes in ini example

* badges: card via Payment Element and PaymentIntents

* badges: fix stale Checkout Session wording in Stripe adapter

* badges: fix stale CheckoutActions reference in card comment

* badges: order shell stylesheet before bootstrap script

* badges: remove development card stand-in

* badges: theme the Stripe card form with the site palette

* badges: exclude web from the Haskell build stage

* badges: unify invoice cancel and mark canceled

* badges: default log level to info

* badges: unify closed-invoice buy-again button

* badges: mute agent connection logs at info level

* badges: show purchase time in local timezone in Your codes

* badges: log service events on own channel, quiet agent

* badges: fold service migrations into one baseline

* badges: run compose on postgres over host network

* badges: use high-res hero art

* badges: add web CI to catch stale builds

* badges: rebuild web shell from committed source

* badges: normalize invoice-code link and columns

* badges: drop unused columns, rename index

* badges: note deferred receipt_hash in migrations

* badges: apply code-review fixes

* badges: reduce comments across service and web

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

* badges: improve web page (#7546)

* badges: improve web page

* improve layout

* improve layout

* fix

* small changes

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

* badges: read one issuer key from the ini

* badges: move and group the service tests

* badges: service fixes (#7567)

* badges: match the redeem error wording in tests

* badges: drop unused imports in the bot tests

* badges: cancel Stripe orders when they expire

* badges: correct the Stripe config and docs

* badges: refuse to revoke a redeemed code

* badges: make the fake Stripe cancel like Stripe

* badges: limit replayed webhook deliveries

---------

Co-authored-by: sh <37271604+shumvgolove@users.noreply.github.com>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
Co-authored-by: shum <github.shum@liber.li>
Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
2026-09-25 09:01:51 +00:00
EvgenyandEvgeny @ SimpleX Chat 64014cd8b0 tests: stabilize (#7576)
* tests: stabilize

* query plans

* fix test

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-24 12:30:31 +01:00
EvgenyandEvgeny @ SimpleX Chat 9a9ce70b2f core: fix connecting via prepared connection with contact card (#7575)
* core: fix connecting via prepared connection with contact card

* simplify

* merge transactions

* update query plans

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-24 08:11:29 +01:00
EvgenyandEvgeny @ SimpleX Chat 3af6e2abfe core: store extended contact and group preferences, for forward compatibility (#7506)
* core: store extended contact and group preferences, for forward compatibility

* simiplify

* fix

* fix bot api types

* query plans

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-23 23:25:20 +01:00
EvgenyandEvgeny @ SimpleX Chat 23136f1cd5 core: update agent API for connections (#7574)
* core: update agent API for connections

* update simplexmq

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-09-23 21:29:41 +01:00
spaced4ndy 150897d637 core, ui: alert the user when badge renewal is failing (#7532) 2026-09-22 12:55:08 +00:00
sh c8f20bcc91 core, libs: configurable queue size, library fixes (#7542)
* core: add chat_migrate_init_queue FFI export

* bots: fix BadgeServiceErrorCode API type

* nodejs: pass required command fields

* nodejs: fix migration error types

* nodejs: install libsimplex from SIMPLEX_LIBS_DIR

* nodejs: add queue size option

* nodejs: regenerate docs

* python: add queue size option

* bots: pass incognito in APIConnect

* nodejs: accept documented success responses

* python: accept documented success responses

* nodejs: dispatch each bot message once

* nodejs: fix startChat events loop lifecycle

* nodejs, python: parse multi-line bot commands

* nodejs: fix file buffer handling in addon

* nodejs: keep events loop when chat stop fails

* python: fix send_and_wait race, load lib off loop

* python: make queue size export optional

* nodejs: receive events on a dedicated thread

* nodejs: release haskell thread after receive

* python: receive on a dedicated thread per chat

* python: test receive shutdown order

* nodejs: one receive thread per chat controller

* nodejs: harden receiver shutdown and tests

* nodejs: stop chat before closing store

* python: stop chat before closing store

* nodejs, python: harden close regression and retry

* python: free results with ucrt on windows

* nodejs: enable c++ exceptions on mac and windows
2026-09-19 12:18:46 +01:00