fix(auth): tighten refresh session revocation

This commit is contained in:
2026-05-13 15:04:37 +08:00
parent b13870f71b
commit 4fecf9c975
36 changed files with 1664 additions and 170 deletions

View File

@@ -38,7 +38,7 @@ import {
logoutAuthUser,
redeemRegistrationInviteCode,
resetPassword,
revokeAuthSession,
revokeAuthSessions,
sendPhoneLoginCode,
setStoredLastLoginPhone,
startWechatLogin,
@@ -121,6 +121,7 @@ export function AuthGate({ children }: AuthGateProps) {
useState<PlatformSettingsSection | null>(null);
const [sessions, setSessions] = useState<AuthSessionSummary[]>([]);
const [loadingSessions, setLoadingSessions] = useState(false);
const [revokingSessionIds, setRevokingSessionIds] = useState<string[]>([]);
const [auditLogs, setAuditLogs] = useState<AuthAuditLogEntry[]>([]);
const [loadingAuditLogs, setLoadingAuditLogs] = useState(false);
const [riskBlocks, setRiskBlocks] = useState<AuthRiskBlockSummary[]>([]);
@@ -167,6 +168,7 @@ export function AuthGate({ children }: AuthGateProps) {
setSettingsEntryMode('settings');
setInitialSettingsSection(null);
setSessions([]);
setRevokingSessionIds([]);
setAuditLogs([]);
setRiskBlocks([]);
setLoginCaptchaChallenge(null);
@@ -691,6 +693,7 @@ export function AuthGate({ children }: AuthGateProps) {
loadingRiskBlocks={loadingRiskBlocks}
loadingSessions={loadingSessions}
loadingAuditLogs={loadingAuditLogs}
revokingSessionIds={revokingSessionIds}
isHydratingSettings={settings.isHydratingSettings}
isPersistingSettings={settings.isPersistingSettings}
settingsError={settings.settingsError}
@@ -752,14 +755,17 @@ export function AuthGate({ children }: AuthGateProps) {
setLoadingAuditLogs(false);
}
}}
onRevokeSession={async (sessionId) => {
onRevokeSession={async (session) => {
const sessionIds =
session.sessionIds.length > 0
? session.sessionIds
: [session.sessionId];
setRevokingSessionIds((current) =>
Array.from(new Set([...current, session.sessionId])),
);
try {
await revokeAuthSession(sessionId);
setSessions((current) =>
current.filter(
(session) => session.sessionId !== sessionId,
),
);
await revokeAuthSessions(sessionIds);
setSessions(await getAuthSessions());
setAuditLogs(await getAuthAuditLogs());
} catch (revokeError) {
setError(
@@ -767,6 +773,10 @@ export function AuthGate({ children }: AuthGateProps) {
? revokeError.message
: '移除登录设备失败,请稍后再试。',
);
} finally {
setRevokingSessionIds((current) =>
current.filter((id) => id !== session.sessionId),
);
}
}}
onLogoutAll={logoutAllSessions}
@@ -795,11 +805,8 @@ export function AuthGate({ children }: AuthGateProps) {
setUser(nextUser);
}}
onChangePassword={async (currentPassword, newPassword) => {
const nextUser = await changePassword(
currentPassword,
newPassword,
);
setUser(nextUser);
await changePassword(currentPassword, newPassword);
clearLocalAuthenticatedState();
}}
/>
) : null}