Suite: entitle the positions above our team root, not just below it
The org test only ever looked downward: you are in if a root appears in your upline chain. The founders and contract owners sit ABOVE #21, so #2 - a Corona position that has been here since the beginning - was told "this position isn't inside our team's organization" and shown a locked wall. That is backwards. Their positions are the reason the contract exists. Each root's own upline is now entitled as well, which covers the chain up through #2 and the root account. A position's upline is fixed at registration, so it is resolved once and memoised rather than walked per request. Nothing else changes: level still comes from the contract, the allowlist and level-override behave as before, and members below the root are unaffected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -686,6 +686,23 @@ async function handleApi(req,res,pathname){
|
||||
if(r.error)return json(res,401,{error:r.error});
|
||||
return json(res,200,{ok:true,id:r.id},{'Set-Cookie':messages.sessionCookie(r.token)});
|
||||
}
|
||||
// Positions on the team root's own upline - i.e. everyone above us, up to and
|
||||
// including the contract root. Fixed at registration, so cache indefinitely.
|
||||
let _suiteUpCache=null, _suiteUpKey='';
|
||||
async function suiteRootUpline(roots){
|
||||
const key=roots.join(',');
|
||||
if(_suiteUpCache&&_suiteUpKey===key)return _suiteUpCache;
|
||||
const out=[];
|
||||
for(const r of roots){
|
||||
try{
|
||||
const rd=await chain.memberPublic(r);
|
||||
if(rd&&Array.isArray(rd.uplineChain))rd.uplineChain.forEach(x=>{const n=Number(x);if(n&&!out.includes(n))out.push(n);});
|
||||
}catch(e){}
|
||||
}
|
||||
if(out.length){_suiteUpCache=out;_suiteUpKey=key;}
|
||||
return out;
|
||||
}
|
||||
|
||||
// ── Circle Suite entitlement helper (shared by suite-me and the tools) ────
|
||||
async function suiteEntitlement(req){
|
||||
const s=messages.authFromCookie(req);
|
||||
@@ -701,7 +718,14 @@ async function handleApi(req,res,pathname){
|
||||
const cfg=getConfig();
|
||||
const roots=String(cfg.teamRootId||cfg.orgRootId||'21').split(',').map(x=>Number(x.trim())).filter(Boolean);
|
||||
const chainIds=Array.isArray(d.uplineChain)?d.uplineChain.map(Number):[];
|
||||
const inOrg=roots.some(r=>Number(d.id)===r||chainIds.includes(r));
|
||||
// The org test only looks DOWNWARD: you are in if a root sits in your upline.
|
||||
// The people ABOVE our root - the founders and contract owners, up through
|
||||
// position #2 and the root account - can never pass that, yet the Suite is
|
||||
// as much theirs as ours. Walk each root's own upline and entitle those
|
||||
// positions too. Registration fixes a position's upline permanently, so this
|
||||
// is computed once and memoised rather than hit on every request.
|
||||
const upIds=await suiteRootUpline(roots);
|
||||
const inOrg=roots.some(r=>Number(d.id)===r||chainIds.includes(r))||upIds.includes(Number(d.id));
|
||||
const allow=String(cfg.suiteAllowlist||'').split(',').map(x=>Number(x.trim())).filter(Boolean);
|
||||
const beta=allow.length>0;
|
||||
const allowed=!beta||allow.includes(Number(d.id));
|
||||
|
||||
Reference in New Issue
Block a user