实现账号绑定、持久登录与跨设备对局恢复
CI / test (ubuntu-latest, node 22) (push) Failing after 33m10s
CI / test (ubuntu-latest, node 24) (push) Failing after 34m41s
CI / tooling (lint, imports, typecheck) (push) Failing after 36m11s
CI / test (windows-latest, node 22) (push) Canceled after 0s
CI / test (windows-latest, node 24) (push) Canceled after 0s
CI / test (ubuntu-latest, node 22) (push) Failing after 33m10s
CI / test (ubuntu-latest, node 24) (push) Failing after 34m41s
CI / tooling (lint, imports, typecheck) (push) Failing after 36m11s
CI / test (windows-latest, node 22) (push) Canceled after 0s
CI / test (windows-latest, node 24) (push) Canceled after 0s
This commit is contained in:
1 parent
488db49f11
commit
7c25c89992
62 files changed
+6855
-1005
No files matched your search
@@ -746,6 +746,7 @@ export function createIdentity(deps = {}) {
|
||||
let initPromise = null;
|
||||
let initialized = false;
|
||||
let resumeBusy = false;
|
||||
let explicitClaim = false; // account entry POST supplied the token; do not persist until welcome
|
||||
let current = null; // token this tab uses (null = let the server create a session)
|
||||
let resolving = null; // { hashes: Set<hash>, taken: Set<hash> } while init() waits for claims
|
||||
let owned = sget(session, K_TOKEN);
|
||||
@@ -811,6 +812,7 @@ export function createIdentity(deps = {}) {
|
||||
// The original page can reappear after resume's query but before its hello. Keep our old
|
||||
// session in storage and give back the tentative selection immediately in that interval.
|
||||
if (current && tokenHash(current) === hash) {
|
||||
explicitClaim = false;
|
||||
if (current === owned) {
|
||||
owned = null; welcomeAt = null; welcomed = false;
|
||||
sdel(session, K_WELCOME);
|
||||
@@ -911,6 +913,13 @@ export function createIdentity(deps = {}) {
|
||||
} catch { return false; }
|
||||
finally { resumeBusy = false; }
|
||||
},
|
||||
/** Select an authenticated account entry token without treating an unacknowledged hello as a saved session. */
|
||||
stageToken(token) {
|
||||
if (!isToken(token)) return false;
|
||||
current = token;
|
||||
explicitClaim = true;
|
||||
return true;
|
||||
},
|
||||
/** @returns {string} remembered player name ('' if none) */
|
||||
loadName: () => (sget(local, K_NAME) || '').slice(0, 64),
|
||||
/** @param {string} name */
|
||||
@@ -924,6 +933,7 @@ export function createIdentity(deps = {}) {
|
||||
},
|
||||
/** A shared candidate must never replace a connected session, including a hello already in flight. */
|
||||
getTokenClaim() {
|
||||
if (explicitClaim) return { noReplace: false };
|
||||
return current === owned && owned
|
||||
? { noReplace: false, ...(welcomeAt != null ? { claimAt: welcomeAt } : {}) }
|
||||
: { noReplace: true };
|
||||
@@ -935,6 +945,7 @@ export function createIdentity(deps = {}) {
|
||||
/** @param {string} token from `welcome` */
|
||||
saveToken(token) {
|
||||
if (!isToken(token)) return;
|
||||
explicitClaim = false;
|
||||
if (current !== token) rememberMatch(null);
|
||||
if (owned !== token || welcomeAt == null) welcomeAt = now();
|
||||
owned = token;
|
||||
@@ -946,6 +957,7 @@ export function createIdentity(deps = {}) {
|
||||
},
|
||||
/** Forget this tab's token (e.g. the server said the session is invalid). */
|
||||
clearToken() {
|
||||
explicitClaim = false;
|
||||
rememberMatch(null);
|
||||
const t = current || sget(session, K_TOKEN);
|
||||
current = null;
|
||||
|
||||
Reference in new issue
Block a user