feat(desktop): implement phase 2 native capabilities
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled

This commit is contained in:
Cheng Zhou
2026-06-30 21:21:55 +08:00
parent 7c721d4e5c
commit 628ff8828b
64 changed files with 3516 additions and 222 deletions
+14 -14
View File
@@ -1,7 +1,7 @@
import router from "../router";
import { useAuthStore } from "../store/auth";
import { useSessionStore } from "../store/session";
import { getToken, setToken, clearToken } from "../utils/auth";
import { getToken, setToken } from "../utils/auth";
import { extendToken } from "../api/authClient";
import { parseJwtExp } from "./jwt";
@@ -30,7 +30,7 @@ const getTimeoutAt = (session: ReturnType<typeof useSessionStore>) =>
const reconcileSessionState = (now: number = Date.now()) => {
const session = useSessionStore();
if (now >= getTimeoutAt(session)) {
forceLogout(LOGOUT_REASON_TIMEOUT);
void forceLogout(LOGOUT_REASON_TIMEOUT);
return false;
}
return true;
@@ -56,11 +56,11 @@ const handleBroadcast = (message: BroadcastMessage) => {
}
if (message.type === "TOKEN_UPDATED") {
auth.setToken(message.token);
setToken(message.token);
void setToken(message.token);
session.resetActivity();
}
if (message.type === "LOGOUT") {
performLogout(message.reason);
void performLogout(message.reason);
}
};
@@ -156,25 +156,25 @@ export const consumeLogoutReason = () => {
}
};
const performLogout = (reason?: string) => {
const performLogout = async (reason?: string) => {
setLogoutReason(reason);
const auth = useAuthStore();
const session = useSessionStore();
auth.logout();
const logoutPromise = auth.logout();
session.resetActivity();
clearToken();
router.replace("/login");
await logoutPromise;
};
export const forceLogout = (reason?: string) => {
performLogout(reason);
export const forceLogout = async (reason?: string) => {
await performLogout(reason);
broadcast({ type: "LOGOUT", reason });
};
const updateToken = (token: string) => {
const updateToken = async (token: string) => {
const auth = useAuthStore();
auth.setToken(token);
setToken(token);
await setToken(token);
broadcast({ type: "TOKEN_UPDATED", token });
};
@@ -194,15 +194,15 @@ export const extendAccessToken = async (reason: "early" | "response-401") => {
try {
const { data } = await extendToken(token);
session.setLastExtendAt(Date.now());
updateToken(data.accessToken);
await updateToken(data.accessToken);
return { token: data.accessToken, authFailed: false };
} catch (err: any) {
const status = err?.response?.status;
if (status === 401) {
forceLogout(LOGOUT_REASON_AUTH_EXPIRED);
await forceLogout(LOGOUT_REASON_AUTH_EXPIRED);
authFailed = true;
} else if (status === 403) {
forceLogout(LOGOUT_REASON_AUTH_EXPIRED);
await forceLogout(LOGOUT_REASON_AUTH_EXPIRED);
authFailed = true;
}
return { token: null, authFailed };