<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinos-server.git/routes, branch master</title>
<subtitle>coinos server — legacy coinos.io backend (Lightning, on-chain, Liquid)</subtitle>
<id>https://git.coinos.io/coinos-server.git/atom?h=master</id>
<link rel='self' href='https://git.coinos.io/coinos-server.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/'/>
<updated>2026-10-13T23:23:37Z</updated>
<entry>
<title>users: let a password unlock the encrypted nostr key for any session</title>
<updated>2026-10-13T23:23:37Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-13T23:23:37Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=12349761c03e769e1d54e878746a10d0a464b38d'/>
<id>urn:sha1:12349761c03e769e1d54e878746a10d0a464b38d</id>
<content type='text'>
/me only reports hasnsec now, so sessions that didn't start with a
password login had no way to reveal or sign with their key. POST /nsec
returns it after re-checking the password, under the login per-IP
failure limit.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01UjHzoBmW1iPpEe5qC2LDYB
</content>
</entry>
<entry>
<title>login: drop the unused per-username failure counter</title>
<updated>2026-10-13T14:52:33Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-13T14:52:33Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=d1a12bc0585aa583263362304218803ebf0afa9a'/>
<id>urn:sha1:d1a12bc0585aa583263362304218803ebf0afa9a</id>
<content type='text'>
The counter was incremented on every failed login and read but never
acted on; the per-IP limits do the throttling. Its keys never expired
and had grown to most of the keyspace.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01UjHzoBmW1iPpEe5qC2LDYB
</content>
</entry>
<entry>
<title>users: keep the encrypted nostr key and 2FA seed away from bearer tokens</title>
<updated>2026-10-08T19:15:15Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-08T19:15:15Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=5df9bc39ac48fdf1b19b00b9b457f9ebc1ee157c'/>
<id>urn:sha1:5df9bc39ac48fdf1b19b00b9b457f9ebc1ee157c</id>
<content type='text'>
/me and user emits return a hasnsec flag instead of the encrypted key, which
is now only sent with a password login or registration. /otpsecret refuses
once 2FA is enabled, and disabling 2FA rotates the seed.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>me: stop reporting archived balance as locked for frozen accounts</title>
<updated>2026-10-08T19:03:38Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-08T19:03:38Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=fbf99d4d212baeae1750cec12244d0f904dfe669'/>
<id>urn:sha1:fbf99d4d212baeae1750cec12244d0f904dfe669</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>email: escape support form HTML and enforce recaptcha v3 score</title>
<updated>2026-10-07T04:12:19Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-07T04:12:19Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=fb7c0086bbfcf17fbaba1ea83a1e3faf2849315b'/>
<id>urn:sha1:fb7c0086bbfcf17fbaba1ea83a1e3faf2849315b</id>
<content type='text'>
Escape the message body, stop accepting a client-supplied subject, strip
control characters from header values, require the expected action and a
minimum score from siteverify, and drop the adminpass captcha bypass.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>payments: lowercase payreq before looking up our own invoices</title>
<updated>2026-10-07T04:12:19Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-07T04:12:19Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=f53e70ed98eb723479b4276c5b621b599fe570a0'/>
<id>urn:sha1:f53e70ed98eb723479b4276c5b621b599fe570a0</id>
<content type='text'>
An uppercase bolt11 for a coinos invoice missed the getInvoice lookup, so
it was paid over lightning to our own node instead of internally. The
listener then saw the sender's payment pointer for that bolt11 and skipped
crediting the recipient. Normalize in POST /payments and nwc pay_invoice.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Evicted accounts can't receive or log in; limit errors say what's happening</title>
<updated>2026-10-04T20:38:24Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-04T20:38:24Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=41018c30a2e03f5ab05be64d419542be0cff7943'/>
<id>urn:sha1:41018c30a2e03f5ab05be64d419542be0cff7943</id>
<content type='text'>
An evicted account no longer gets lightning-address invoices (stops a
scam page's address from minting new ones) or a login token. A send
over the server limit now says withdrawals are temporarily limited
instead of a generic "Problem sending payment" that read as a frozen
account. (Already live since the 2026-10-01 restart.)

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_011bvzKaZosXGHkigcGcSzAR
</content>
</entry>
<entry>
<title>lnurl: budget unauthenticated invoice generation per recipient</title>
<updated>2026-09-29T15:37:47Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-29T15:37:39Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=598a142e852b4682888aceac0d2d8dc39e0f981c'/>
<id>urn:sha1:598a142e852b4682888aceac0d2d8dc39e0f981c</id>
<content type='text'>
GET /pay/:user/:amount and the lnurl callback create a CLN invoice and an
entry in the recipient's invoice list for anyone holding the link, which a
scanner on rotating IPs can do without tripping per-IP limits. Cap fresh
invoices at 120 per recipient per hour (reused invoices don't count).

Also fail cleanly for unknown usernames and skip invoice ids whose records
no longer exist, instead of throwing on the null and breaking the pay page.
Throttle the resulting lnurlp warnings per username.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>logging: throttle log lines that clients can trigger at will</title>
<updated>2026-09-29T15:37:47Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-29T15:37:39Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=4900ecb19ab9c6d279c8771b834fcb29e526a1e0'/>
<id>urn:sha1:4900ecb19ab9c6d279c8771b834fcb29e526a1e0</id>
<content type='text'>
Evicted-JWT replays, blocked sends from frozen or limited accounts and
failed payment retries each logged one line per request, so a looping client
could flood the log, and an evicted token replayed across a proxy pool made
atk-autoban.sh block every IP it saw. Add quiet()/suppressed() in
lib/logging.ts: the first occurrence per key logs as before, repeats within
the window are counted and reported on the next line that gets through. The
evicted-auth summary line is worded so the auto-banner ignores it.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>invoices: don't let a supplied id overwrite another user's invoice</title>
<updated>2026-09-29T15:37:47Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-29T15:37:39Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=e96ad1cea4192a608a7f15896e4b690b57bf8fc9'/>
<id>urn:sha1:e96ad1cea4192a608a7f15896e4b690b57bf8fc9</id>
<content type='text'>
generate() writes invoice:&lt;id&gt; wholesale with the caller's uid, and the old
bolt11 pointer keeps resolving to that id, so passing someone else's invoice
id re-pointed their invoice at the caller's account. Invoice ids aren't
secret (LUD-21 verify URLs, invoice pages, receipts), so refuse an existing
id that belongs to a different user, both in generate() and in POST /invoice
for anonymous pay-page callers. Both fail with "invoice not found" so ids
can't be probed for existence.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
