Commit Graph
15 Commits
Author SHA1 Message Date
SatoshiQaziMuhammed 78fd8b0514 ops: stop requiring an approval that nobody can give (#34)
The rule said one approving review. On a four-person team where the author is
usually the only person awake, that meant every merge went through
`gh pr merge --admin` — so the requirement was not producing review, it was
producing a habit of bypassing the branch rule. A control everyone routes around
is worse than no control: it still shows up green in an audit.

Zero required approvals, and the rest of the protection stays exactly as it was.
Nothing lands on main without a PR; nothing merges with red CI. That is the part
a team this size actually gets value from, and it costs no waiting.

What was being protected here was never code review. It was that nothing reaches
production unnoticed, and that funds cannot move on one person's say-so. Both
live elsewhere: production waits on the environment gate, and fund movement is
going behind on-chain multisig — where a stolen account cannot forge a second
signature the way a collected token can forge a second approval.

Drift check passes against live settings.
2026-08-01 10:31:51 -07:00
SatoshiQaziMuhammed 338472629d fix(auth): put the captcha challenge where the user is looking (#33)
Driving the real login page in a browser showed what shipping this actually
looks like when Cloudflare decides a visitor must click: the submit button sits
on 'Signing in...' while an unnoticed 'Verify you are human' checkbox waits in
the bottom-right corner. Nothing tells the user it is there. They conclude login
is broken, and they are not wrong.

Two changes:

- The challenge is centred over a dimmed backdrop while it is visible, and
  returns to the corner once answered. Detected by measuring the container
  rather than by Turnstile's interactive callbacks: those callbacks are not in
  the documentation this was written against, and a callback name that turns out
  to be wrong fails silently — leaving the challenge in the corner, which is the
  bug being fixed.

- A 90 second cap on waiting for a token. Without it, a challenge nobody answers
  leaves the button spinning forever with no error and no way back. Every caller
  already surfaces a rejection to the user.

The ResizeObserver fallback polls instead of returning a no-op. Doing nothing
there would restore the original bug on those browsers and do it without an
error, which is the worst way for a fix to be missing.
2026-08-01 06:16:44 -07:00
SatoshiQaziMuhammed c26eeee12c feat(auth): require a captcha on the endpoints that send mail (#32)
Signup had no bot protection. The account itself was never the prize — GoTrue
refuses a session until the address is confirmed, and 0 of the 2 unconfirmed
accounts on record ever signed in. The prize is our mail: /signup and /recover
send to whatever address the caller types, so a stranger could make
pezkuwichain.io mail thousands of people who never asked for it. Sending
reputation takes months to rebuild and every product on the domain shares it.

Rate limiting alone was not enough. GoTrue defaults to 30 emails/hour, which is
720 a day to attacker-chosen recipients; tightening it to 15 halves the number
without changing what is possible.

Verification runs inside GoTrue, not here. It POSTs to siteverify with the
widget secret before /signup, /recover, /resend, /magiclink, /otp and /token
with grant_type=password. Adding our own check in the frontend or a proxy would
protect nothing, because /auth/v1/signup is reachable directly.

One shared widget in execute mode rather than one per form: some of these are
buttons with nowhere to put a checkbox, and interaction-only appearance keeps
the challenge invisible unless Cloudflare asks for one. Tokens are single-use,
so each call renders fresh and tears down the previous widget.

Six call sites, matching the six protected endpoints — password login included,
since /token with grant_type=password is enforced. Refresh-token grants are
exempt, so open sessions are unaffected.

Site key travels as a build arg like the WalletConnect id: it is public by
construction, visible in the bundle. Only the secret is privileged and it lives
in GoTrue's env on the auth host.

Ships ahead of enforcement. Turning captcha on server-side before the frontend
sends tokens would break every login and signup in the same instant.
2026-08-01 03:45:51 -07:00
SatoshiQaziMuhammed 35884cb8c9 ci: put the approve button back in Telegram (#31)
Moving approval to a GitHub Environment fixed the failure it was meant to fix,
and quietly broke something that worked. The old gate polled a file for 30
minutes holding a runner; on 2026-07-30 the window expired unseen and cancelled
a deploy. What replaced it holds the run for 30 days on no runner and records
who approved which SHA — but only answers to a browser. For a single approver
that means being at a PC for a deploy to move.

The notification now carries Approve and Reject buttons that answer the
environment's pending deployment through @pexsecBot. Nothing about the
enforcement changes: the protection rule still holds the deploy, and the bot
only presses the button as the reviewer. If the bot, its host, or its token is
gone, a release waits — none of that lets an unapproved deploy through. The
GitHub link stays as the fallback.

Bot side: pezkuwichain/pexsec-bot (new private repo — it had been an
unversioned copy on NEW-10 with three .bak files beside it).
2026-08-01 02:30:20 -07:00
SatoshiQaziMuhammed f9d784f3de Merge pull request #29 from pezkuwichain/feat/2fa-login-gate
feat(auth): actually ask for 2FA at login
2026-07-31 23:07:22 -07:00
SatoshiQaziMuhammed a3fde0dc9d Merge pull request #28 from pezkuwichain/db/baseline-schema
db: replace the migration history with a baseline of the live schema
2026-07-31 20:26:56 -07:00
SatoshiQaziMuhammed cec1dcf9be Merge pull request #27 from pezkuwichain/fix/remove-dead-email-verification
fix(security): remove the dead email-verification function
2026-07-31 20:26:51 -07:00
SatoshiQaziMuhammed b20cfc84ef Merge pull request #26 from pezkuwichain/ci/extend-deploy-approval-window
ci: gate deploys on a GitHub Environment instead of a hand-rolled wait loop
2026-07-31 07:27:48 -07:00
SatoshiQaziMuhammed c4b22d0a14 Merge pull request #25 from pezkuwichain/fix/repair-missing-db-functions
fix(db): repair functions their migrations recorded but never created
2026-07-30 14:56:21 -07:00
SatoshiQaziMuhammed e95907ec87 Merge pull request #24 from pezkuwichain/fix/function-authorization
fix(security): identify the caller from their token, not the request body
2026-07-30 04:25:26 -07:00
SatoshiQaziMuhammed 46669aa72d Merge pull request #23 from pezkuwichain/feat/adopt-cloud-functions
feat(supabase): adopt the three functions left behind on the cloud project
2026-07-30 02:40:23 -07:00
SatoshiQaziMuhammed 8cc3935b91 Merge pull request #22 from pezkuwichain/ci/backend-deploy-guard
ci(supabase): ownership gate for shared edge functions + complete 6-locale copy
2026-07-30 02:05:16 -07:00
SatoshiQaziMuhammed bb0b7d4183 Merge pull request #21 from pezkuwichain/ci/backend-deploy-guard
ci: backend indexer deploy — self-contained config + host gate
2026-07-25 21:26:56 -07:00
SatoshiQaziMuhammed 3d786f47d3 Merge pull request #20 from pezkuwichain/audit-remediation
security: P2P fund-custody audit remediation + backend CI/CD (proven-by-execution)
2026-07-25 18:30:22 -07:00
SatoshiQaziMuhammed 14d6da24db Merge pull request #14 from pezkuwichain/redesign
feat(web): authenticated home redesign + Telegram OAuth + SMTP
2026-05-01 10:22:36 +03:00