Repository navigation
Fix SMS + CoinPay sign-in, add passkey sign-up and sign-in - #273
Merged
Merged
Conversation
SMS: Supabase Auth on dev2 had no SMS provider, and the Twilio account it used now rejects every credential (401). Codes now go through GoTrue's Send SMS hook: POST /api/auth/hooks/send-sms verifies the Standard Webhooks signature and sends via Telnyx (TELNYX_API_KEY, TELNYX_SMS_FROM, SEND_SMS_HOOK_SECRET). The hook is exempt from the per-IP auth limit, which would otherwise cap the site at 10 codes a minute. CoinPay: every login was refused because CoinPay reports email_verified=false for all accounts, and /auth never showed ?error=, so it looked like a refresh. Identity is now CoinPay's sub (never the unverified email, which would let anyone claim an address they typed); existing CoinPay accounts carry coinpay_sub and keep working. Errors are shown: popup posts them to the opener, redirect mode via ?error=. The redirect-mode success no longer sets cookies the app never reads; it hands the session to /auth in the URL fragment. Passkeys (@simplewebauthn): create an account with only a username and a passkey, sign in with one tap (discoverable, so no account enumeration), and add/remove passkeys in Settings. RP is the host the browser is on (qrypt.chat or the onion). Sessions come from the shared magic-link bridge (mintSession). Migration 20261006150000_passkeys: RLS on, service role only. /auth: one completeLogin() for CoinPay and passkeys (session storage + the E2EE key lifecycle). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ThreatCrush Security Scan13 finding(s) MEDIUM: 9 | LOW: 4
Snippets are redacted; ThreatCrush never prints matched credential material. |
Contributor
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
A session in the URL fragment let a crafted link sign a victim into the attacker's account (CodeQL js/user-controlled-bypass). The callback now sets a 2-minute cookie on /auth that the page reads once and deletes; another site cannot set it. Also stop logging the provider's error text and only consult ?error= when there is no code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
This fixes two broken sign-in paths on qrypt.chat and adds passkeys.
SMS login: "Unable to get SMS provider"
Why it failed:
The fix: GoTrue now delivers codes through its Send SMS hook.
POST /api/auth/hooks/send-smsverifies the Standard Webhooks signature (webhook-id,-timestamp,-signature, with a 5-minute window).TELNYX_API_KEY,TELNYX_SMS_FROM,SEND_SMS_HOOK_SECRET. They're inapp.envon dev2 and in theqryptchat-web--prodvault./api/auth/hooks/*uses the webhook rate limit instead of the per-IP auth limit. Every hook call comes from GoTrue's single address, so the auth limit would have capped the whole site at 10 codes a minute.GoTrue's side is enabled after this deploys (
GOTRUE_HOOK_SEND_SMS_*involumes/auth/auth.env, cli-tools #136).CoinPay login "just refreshes"
Why it failed:
email_verified: falsefor every account, since its 2026-08-19 security fix./authnever displayed?error=. In popup mode the popup reloaded/auth, and that looked like a refresh./chatbounced you straight back to/auth.The fix:
sub, never the unverified email. Linking by email would let anyone claim an account by typing its address into CoinPay.coinpay_subin their metadata and keep working.<sub>@coinpay.qrypt.chat, and the email CoinPay sent is kept as metadata only.?error=./authshows a readable message for each./authin the URL fragment. A fragment never reaches a server log.Passkeys (
@simplewebauthn/server+/browserv14)qcuses (mintSession).20261006150000_passkeys:webauthn_credentialsandwebauthn_challenges, RLS on, service role only. It is already applied on dev2./authCoinPay and passkeys now share one
completeLogin()for session storage and the key lifecycle, instead of separate copies.Tests
19 new tests:
sub, ignoring a matching emailResults:
bun run test:ci: 612/612.next buildpasses.🤖 Generated with Claude Code