Repository navigation
Credit codes + invites; fix domain takeover and email-based account linking - #140
Merged
Merged
Conversation
…ount linking Credit codes (@profullstack/redeem-credits 0.2.0, unit pro_days) grant days of the paid affiliate plan ($1/mo) through plan_grants, one row per (account, source), so every grant is idempotent. Invites (@profullstack/affiliates 0.3.0): 3 per account, /invites, /i/<code>, accepted at sign-up, CoinPay sign-in or on the page; the bonus (30 days each side) waits for an emailed confirm link. Security fixes found in the sweep: - any signed-in user (or an anonymous sign-up) could claim a domain another account holds (addParkedDomain reassigned it, upsertTenant overwrote the page), e.g. moshscript.com / moshcode.sh; - CoinPay sign-ins were matched to accounts by email, which CoinPay never verifies (email_verified=false): bound by CoinPay sub now; - ADMIN_EMAILS promoted any account with that (unverified) email to admin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
ThreatCrush Security Scan22 finding(s) HIGH/CRITICAL: 2 | MEDIUM: 14 | LOW: 6
Snippets are redacted; ThreatCrush never prints matched credential material. |
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.
What
Credit codes (
@profullstack/redeem-credits0.2.0, unitpro_days, prefixMOSH-). A code adds days of the paid affiliate plan ($1/mo: set your own commission rate instead of the 80% floor). Grants go through one path,grantPaidDays()(lib/plan.ts), intoplan_grants(PK account_id + source = idempotent;code:<id>,invite:<id>:inviter|invitee). The plan is paid whileaffiliates.plan='paid'or granted days remain; days queue after each other and are computed on read, so concurrent grants never overwrite each other. A future $1/mo checkout should callgrantPaidDays()with its payment id./invites#redeem("Have a code?", linked from the dashboard Affiliates tab),POST /api/credits {code}(session or API key),GET /api/credits.docker exec moshcodingcom-app-1 bun scripts/credit-codes.ts mint --days 30 --label "for X" [--max N] [--expires-days N](alsolist,revoke <id>,quota <email> <n>).Invites (
@profullstack/affiliates0.3.0): 3 per account,/invites,/i/<code>(cookiemc_invite, 30 days). Accepted at email sign-up, CoinPay sign-in, or by pasting the code on/invites(another device). One accepted invite per account (already_invited; the refused invite stays unused). Only accounts <= 7 days old can accept; senders must be >= 24 h old. Neither sign-in here verifies email, so the bonus (30 days each side,INVITE_BONUS_DAYS) waits ininvite_bonusesuntil the invitee clicks a signed link emailed to them (/i/confirm?t=, any browser, 14 days). No bonus for throwaway domains (mailchecker), the inviter's own mailbox (+tag / Gmail dots), staff; inviter half capped at 5 per 30 days (INVITE_MONTHLY_CAP). The existing?ref=/mc_refaffiliate program is untouched (noaff.attribute()).Security fixes (rule 10/11 sweep)
addParkedDomaindidON CONFLICT (domain) DO UPDATE SET account_id = excluded.account_id, andupsertTenantoverwrote any row. Any signed-in user (POST /api/tenant {addDomain}then?dn=), or an anonymous email sign-up withdomain=moshscript.com, took over another account's page, including Anthony's moshscript.com / moshcode.sh / chovy.com. Now a domain held by another account (parked, tenant row incl. owner-less staff rows, or account page domain) is refused (409), andupsertTenantonly updates a row the same account owns.email_verified=false(no verification flow), so registering a CoinPay account with someone's address opened their moshcoding account. Accounts are now bound by CoinPaysub(accounts.coinpay_sub, unique). The deploy that adds the column binds the 5 existing CoinPay users to their current accounts once. After that, a CoinPay sign-in can only claim an account with no password and no binding./api/affiliate/joinwith it).findOrCreateAccountByEmailnever grants admin now; existingis_adminrows are unchanged.Tests
bun test tests/: 272 pass (11 new intests/credits-invites.test.mjs, also run green against Postgres withTEST_PG_URL).tsc --noEmitclean,bun run buildok. Schema change dry-run on a restored copy of prod: bindings and tenant configs as expected.🤖 Generated with Claude Code