Carry the placement choice with the referral too

Auditing the rest of the prospect paths after Terry's leak. Every entry
point funnels through /join/<id> — the Telegram Mini App redirects there,
member page-builder pages link there, the public /my/<id> share panel
links there — so the cookie covers all of them.

One gap left: ?direct=1 is the inviter's explicit decision to take the
join under themselves rather than route it down their leg, and only the
id was being remembered. A prospect who opened a direct link and then
wandered through the nav came back through the moving link instead — the
opposite of what the shared link asked for.

The flag now rides along in its own cookie, and both /start and /join-now
prefer an explicit choice over the position's default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-18 11:25:34 -05:00
parent 2b36a29a68
commit 8987451cf6
3 changed files with 19 additions and 4 deletions
+8 -1
View File
@@ -1793,7 +1793,14 @@ function serveMemberPage(req,res,file,kind,id){
// to a stranger. The invite is the referral, so it has to outlive the one page it landed
// on. 30 days, Lax so it survives a normal click-through from anywhere.
if(kind==='join'&&/^\d{1,15}$/.test(String(id))){
head['Set-Cookie']='rmc_ref='+id+'; Path=/; Max-Age=2592000; SameSite=Lax'+(IS_PROD?'; Secure':'');
const attrs='; Path=/; Max-Age=2592000; SameSite=Lax'+(IS_PROD?'; Secure':'');
const ck=['rmc_ref='+id+attrs];
// ?direct=1/0 is the inviter's explicit choice about placement, so it has to travel with
// the referral. Without it a prospect who wandered off the invite page would come back
// through the moving link instead — the opposite of what the shared link asked for.
const dq=new URL(req.url,'http://x').searchParams.get('direct');
if(dq==='1'||dq==='0')ck.push('rmc_direct='+dq+attrs);
head['Set-Cookie']=ck;
}
res.writeHead(200,securityHeaders(head));
res.end(html);