mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-10-18 14:51:26 +02:00
feat(auth): sign-in-with-wallet — adopt an existing wallet-linked account instead of erroring
A Smirk wallet that already owns another account no longer fails with 'already linked to another account'. Ownership is cryptographically proven, so it's a login: the server re-points that account to the current socket and returns its session token; the client persists it and reloads to re-establish as that account. Fixes a returning user being unable to sign in from a fresh browser session. NOTE: touches the identity/session path — verify live (sign in with a wallet already linked to another account -> lands on that account with its address/credits).
This commit is contained in:
@@ -97,6 +97,16 @@ const SmirkAuth = {
|
||||
provenPublicKey = result.pubkey;
|
||||
}
|
||||
|
||||
// Sign-in-with-wallet adoption: if this wallet already owned an account, the server signed
|
||||
// us into it and returned that account's session token. Persist it and reload so the whole
|
||||
// session re-establishes as that account (credits, address, history).
|
||||
if (verifyData && verifyData.adopted && verifyData.sessionToken) {
|
||||
try { localStorage.setItem('wownerogue_token', verifyData.sessionToken); } catch (_) { /* ignore */ }
|
||||
$('#messages').append($('<li class="status">').text('🔑 Signed in to your wallet-linked account. Reloading…'));
|
||||
setTimeout(function () { window.location.reload(); }, 700);
|
||||
return { success: true, linked: true, adopted: true, address: verifyData.address || null };
|
||||
}
|
||||
|
||||
// Step 3: Get wallet addresses and auto-set payout address
|
||||
// Note: the proven public key is a pubkey (hex), NOT an address.
|
||||
// We need to call getAddresses() to get the actual WOW address.
|
||||
|
||||
+18
-4
@@ -46,14 +46,28 @@ module.exports = function createAuthRoutes(ctx) {
|
||||
|
||||
const userId = userResult.rows[0].id;
|
||||
|
||||
// Reject linking a wallet already bound to a different account.
|
||||
// Sign-in-with-wallet: if this proven wallet already owns a DIFFERENT account, that is a
|
||||
// LOGIN to that account, not a hijack (ownership is cryptographically proven). Adopt it —
|
||||
// re-point that user to the current socket and hand the client its session token so the
|
||||
// browser re-establishes as that account. (Previously this threw "already linked to another
|
||||
// account", which blocked a returning user from signing in on a fresh browser session.)
|
||||
const existingLink = await db.query(`
|
||||
SELECT id FROM users WHERE smirk_public_key = $1 AND id != $2
|
||||
SELECT id, anon_token, payout_address FROM users WHERE smirk_public_key = $1 AND id != $2 LIMIT 1
|
||||
`, [provenKey, userId]);
|
||||
|
||||
if (existingLink.rows.length > 0) {
|
||||
throw new ValidationError('Wallet already linked', {
|
||||
safeMessage: 'This wallet is already linked to another account.'
|
||||
const owner = existingLink.rows[0];
|
||||
await db.query(
|
||||
`UPDATE users SET socket_id = $1, last_seen = NOW() WHERE id = $2`,
|
||||
[socketId, owner.id]
|
||||
);
|
||||
return res.json({
|
||||
success: true,
|
||||
linked: true,
|
||||
adopted: true,
|
||||
sessionToken: owner.anon_token || null,
|
||||
address: owner.payout_address || null,
|
||||
message: 'Signed in to your wallet-linked account.'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user