Join page names the owner of the link it was opened with, and tells a member when they are previewing their own page

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-13 07:54:29 -05:00
parent 6ca287042f
commit 6589930945
3 changed files with 15 additions and 9 deletions
+3 -2
View File
@@ -88,10 +88,11 @@
// sponsor line (the link opened most recently sets the sponsor; it locks at account creation)
let sponsorName = '';
fetch('/api/sponsor').then(r => r.json()).then(sp => {
const linkTok = (location.pathname.match(/^\/join\/([^/?#]+)/) || [])[1] || '';
fetch('/api/sponsor' + (linkTok ? '?ref=' + encodeURIComponent(linkTok) : '')).then(r => r.json()).then(sp => {
if (sp && sp.invited && sp.name) {
sponsorName = sp.name;
$('jnSponName').textContent = sp.name;
$('jnSponName').textContent = sp.name + (sp.own ? ' (this is your own invite page; visitors see your name here)' : '');
if (sp.avatarUrl) { $('jnSponImg').src = sp.avatarUrl; $('jnSponImg').hidden = false; }
$('jnSpon').hidden = false;
}
+1 -1
View File
@@ -157,6 +157,6 @@
</div>
</div>
<script src="/assets/common.js?v=20260913a"></script>
<script src="/assets/join.js?v=20260912d"></script>
<script src="/assets/join.js?v=20260913a"></script>
</body>
</html>
+11 -6
View File
@@ -796,14 +796,19 @@ const server = http.createServer(async (req, res) => {
// orphan fallback: an unresolvable/absent sponsor (dead link, no link) lands
// the new member under the configured catch position (#1) instead of root
if (!sponsorId && (!acct || acct.memberId !== (Number(siteConfig().defaultSponsorId) || 1))) sponsorId = Number(siteConfig().defaultSponsorId) || 1;
let name = null, avatarUrl = null;
if (tok) {
const t = tok.toLowerCase();
let name = null, avatarUrl = null, own = false;
// the join page names the owner of the LINK it was opened with (?ref=token), not the visitor's own
// sponsor: a member previewing their own invite page was seeing their upline's name (Jim, 2026-09-13)
let showTok = String(u.searchParams.get('ref') || '').trim().toLowerCase();
if (showTok && JOIN_ALIASES[showTok]) showTok = JOIN_ALIASES[showTok];
const nameTok = showTok || tok;
if (nameTok) {
const t = nameTok.toLowerCase();
let a = await accounts.byCode(t); if (!a) a = await accounts.byUsername(t);
if (!a && /^\d+$/.test(tok)) a = await accounts.byMemberId(Number(tok));
if (a) { name = a.username ? '@' + a.username : (a.memberId ? 'member #' + a.memberId : null); avatarUrl = a.avatarUrl || null; }
if (!a && /^\d+$/.test(nameTok)) a = await accounts.byMemberId(Number(nameTok));
if (a) { name = a.username ? '@' + a.username : (a.memberId ? 'member #' + a.memberId : null); avatarUrl = a.avatarUrl || null; own = !!(acct && a.email === acct.email); }
}
return json(res, 200, { ref: tok, sponsorId, invited: !!tok, name, avatarUrl });
return json(res, 200, { ref: tok, sponsorId, invited: !!(tok || showTok), name, avatarUrl, own });
}
if (p === '/api/stats' && req.method === 'GET') {
let members = 0; try { members = await chain.memberCount(); } catch (e) {}