Skip to content

feat: Sign in with CoinPay - #262

Merged
sh1pt-actions-fleet[bot] merged 1 commit into
mainfrom
feat/coinpay-signin
Oct 29, 2026
Merged

sh1pt-actions-fleet[bot] merged 1 commit into
mainfrom
feat/coinpay-signin

Conversation

@sh1pt-actions-fleet

Copy link
Copy Markdown
Contributor

CoinPay is the fleet's master account: this adds Sign in with CoinPay to rssamplifier.com.

  • /login and /signup: "Sign in with CoinPay" is the first panel (SignInPanels); the emailed link and passkeys are unchanged.
  • /account#coinpay: Connect / Disconnect CoinPay; "Add an email address" for an account made by CoinPay.
  • Flow (@profullstack/coinpay-onboard 0.3.1): auth code + PKCE S256 + state + nonce, exact redirect https://rssamplifier.com/api/v1/coinpay/oauth/callback, client secret on the code exchange, id_token iss/aud/exp/nonce check, userinfo sub match. State is pinned to the browser by an httpOnly cookie and kept server-side as a single-use coinpay_pending row.
  • STANDING sub rule: accounts bind to the CoinPay sub (coinpay_identities). A CoinPay email that matches an existing account never signs into it; a new account gets a coinpay.invalid placeholder and the CoinPay email is stored on the identity row as contact info only. Connect needs a signed-in session and the same session must finish the callback.
  • No email for CoinPay-only accounts until proven: they add one through a mailed sign-in link (login_tokens.claim_user_id); a taken address is refused. Until then they are off the weekly digest and cannot add email alerts (webhooks/push still work).
  • Lockout guards: Disconnect refused when CoinPay is the only way in (no proven address, no passkey); a placeholder account's last passkey cannot be removed once CoinPay is disconnected.
  • Migration 20261029060855_coinpay_identities.sql: two new tables + one nullable column on login_tokens; applied by the poller on boot.
  • The CLI uses API keys from /account, so it is unaffected.

Tests: packages/auth/test/coinpay.test.js (email collision, link needs the same session, forged/missing/replayed state, safe next, disconnect guard, claim link). Full suite green locally against Postgres 17 (db 348, web 519, auth 30, ...).

🤖 Generated with Claude Code

CoinPay is the fleet's master account. Adds "Sign in with CoinPay" as the
first panel on /login and /signup and a CoinPay section on /account
(Connect / Disconnect, add an email), via @profullstack/coinpay-onboard
0.3.1: auth code + PKCE S256 + state + nonce, client secret on the
exchange, id_token iss/aud/exp/nonce and userinfo sub checks.

- Bound by the CoinPay sub (coinpay_identities), never by email. A CoinPay
  email that matches an existing account gets its own new account on a
  coinpay.invalid placeholder; the CoinPay email is contact info only.
- State is pinned to the browser by an httpOnly cookie and spent from a
  server-side coinpay_pending row (single use, 10 minutes).
- Connect needs a session and the same session must finish the callback.
- Disconnect is refused when CoinPay is the only way in; a placeholder
  account's last passkey is kept once CoinPay is gone.
- A CoinPay-only account adds a real address by a mailed sign-in link
  (login_tokens.claim_user_id); a taken address is refused.
- Placeholder accounts are off the digest and cannot add email alerts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​profullstack/​coinpay-onboard@​0.3.17610010093100

View full report

@sh1pt-actions-fleet
sh1pt-actions-fleet Bot merged commit 453777c into main Oct 29, 2026
3 checks passed
@sh1pt-actions-fleet
sh1pt-actions-fleet Bot deleted the feat/coinpay-signin branch October 29, 2026 06:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant