Suite: force the wallet account picker when switching position
Clearing our session was only half the problem. eth_requestAccounts returns whichever account the wallet already has connected to the site - it never opens the picker - so a member holding two positions could sign out, switch accounts in MetaMask, reconnect, and be handed the same address again. Signing with it resolved to the same position, which looked exactly like the switch doing nothing. This is the trap already documented in our own Triple Play guidance, and the Triple Play is what puts members in this situation in the first place. Switching now calls wallet_requestPermissions first, which forces the account selector open. Only on switch, so ordinary single-position sign-ins are unchanged. And if the wallet still returns the same address, the page now says so - naming the address and pointing at the wallet's connected-sites list - instead of silently redisplaying the same position. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -88,6 +88,8 @@
|
|||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
sw.textContent = 'signing out…';
|
sw.textContent = 'signing out…';
|
||||||
try { await fetch('/api/public/signout', { method: 'POST' }); } catch (e) {}
|
try { await fetch('/api/public/signout', { method: 'POST' }); } catch (e) {}
|
||||||
|
// Tell connect() to force the wallet's account picker on the way back in.
|
||||||
|
try { sessionStorage.setItem('rmc.switch', '1'); } catch (e) {}
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
me = null; pips(); render();
|
me = null; pips(); render();
|
||||||
@@ -114,15 +116,40 @@
|
|||||||
try {
|
try {
|
||||||
var eth = await window.RMCWallet.pick();
|
var eth = await window.RMCWallet.pick();
|
||||||
if (!eth) { {var _ia=(window.RMCInApp&&window.RMCInApp.notice('/suite'))||'';if(_ia){err.innerHTML=_ia;if(err.style)err.style.display='block';window.RMCInApp.bind('/suite');}else{err.textContent = 'This browser has no wallet in it. Open this page INSIDE your wallet app instead: open Trust, MetaMask, SafePal or Coinbase, find its Browser (or DApps) tab, and type rmcircle.team/suite into that address bar. On iPhone, Trust no longer has a browser — use MetaMask or SafePal, or ask your sponsor to link you instead.';}} err.style.display = 'block'; btn.disabled = false; btn.textContent = '🔑 Connect wallet — light up my tools'; return; }
|
if (!eth) { {var _ia=(window.RMCInApp&&window.RMCInApp.notice('/suite'))||'';if(_ia){err.innerHTML=_ia;if(err.style)err.style.display='block';window.RMCInApp.bind('/suite');}else{err.textContent = 'This browser has no wallet in it. Open this page INSIDE your wallet app instead: open Trust, MetaMask, SafePal or Coinbase, find its Browser (or DApps) tab, and type rmcircle.team/suite into that address bar. On iPhone, Trust no longer has a browser — use MetaMask or SafePal, or ask your sponsor to link you instead.';}} err.style.display = 'block'; btn.disabled = false; btn.textContent = '🔑 Connect wallet — light up my tools'; return; }
|
||||||
|
// eth_requestAccounts SILENTLY returns whichever account the site is
|
||||||
|
// already connected to - it never opens the picker. So someone holding
|
||||||
|
// several positions can switch accounts in MetaMask all day and still be
|
||||||
|
// handed the first one they ever connected, sign with it, and resolve to
|
||||||
|
// the same position. Asking for permissions first forces the picker open.
|
||||||
|
var wantSwitch = false;
|
||||||
|
try { wantSwitch = sessionStorage.getItem('rmc.switch') === '1'; } catch (e) {}
|
||||||
|
if (wantSwitch) {
|
||||||
|
try { await eth.request({ method: 'wallet_requestPermissions', params: [{ eth_accounts: {} }] }); }
|
||||||
|
catch (pe) { /* wallet may not support it; fall through to the normal request */ }
|
||||||
|
try { sessionStorage.removeItem('rmc.switch'); } catch (e) {}
|
||||||
|
}
|
||||||
var accs = await eth.request({ method: 'eth_requestAccounts' });
|
var accs = await eth.request({ method: 'eth_requestAccounts' });
|
||||||
var account = accs[0];
|
var account = accs[0];
|
||||||
|
var shortAcc = account ? account.slice(0, 6) + '…' + account.slice(-4) : '';
|
||||||
try { await window.RMCWallet.ensureChain(eth); } catch (ce) {}
|
try { await window.RMCWallet.ensureChain(eth); } catch (ce) {}
|
||||||
var ch = await (await fetch('/api/public/msg-challenge', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address: account }) })).json();
|
var ch = await (await fetch('/api/public/msg-challenge', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address: account }) })).json();
|
||||||
if (!ch.message) throw new Error(ch.error || 'Could not start sign-in.');
|
if (!ch.message) throw new Error(ch.error || 'Could not start sign-in.');
|
||||||
var sig = await eth.request({ method: 'personal_sign', params: [ch.message, account] });
|
var sig = await eth.request({ method: 'personal_sign', params: [ch.message, account] });
|
||||||
var vr = await (await fetch('/api/public/msg-verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address: account, signature: sig }) })).json();
|
var vr = await (await fetch('/api/public/msg-verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address: account, signature: sig }) })).json();
|
||||||
if (!vr.ok) throw new Error(vr.error || 'Signature check failed.');
|
if (!vr.ok) throw new Error(vr.error || 'Signature check failed.');
|
||||||
|
var prevId = null;
|
||||||
|
try { prevId = sessionStorage.getItem('rmc.lastId'); } catch (e) {}
|
||||||
await refreshMe();
|
await refreshMe();
|
||||||
|
try {
|
||||||
|
var nowId = (me && me.id) ? String(me.id) : null; // `me` is set by refreshMe() in this same closure
|
||||||
|
if (nowId) sessionStorage.setItem('rmc.lastId', nowId);
|
||||||
|
if (prevId && nowId && prevId === nowId) {
|
||||||
|
err.innerHTML = 'Your wallet handed back the same address (<b>' + shortAcc + '</b>), so this is still position <b>#' + nowId +
|
||||||
|
'</b>. Wallets keep a site connected to one account: open your wallet, find its connected-sites or permissions list, ' +
|
||||||
|
'disconnect <b>rmcircle.team</b>, then tap switch here again and pick the other account.';
|
||||||
|
err.style.display = 'block';
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var m = String((e && e.message) || e);
|
var m = String((e && e.message) || e);
|
||||||
err.textContent = /not registered|no position/i.test(m)
|
err.textContent = /not registered|no position/i.test(m)
|
||||||
|
|||||||
Reference in New Issue
Block a user