mirror of
https://github.com/ivabus/gui
synced 2025-06-08 00:00:27 +03:00
move auth polling strategy to main thread (#546)
* #545 move auth polling strategy to main thread * #545 remove unused * bum v0.1.1 --------- Co-authored-by: neil molina <neil@neils-MacBook-Pro.local>
This commit is contained in:
parent
1a0289f7c1
commit
9f88a1bf5b
8 changed files with 84 additions and 66 deletions
|
@ -196,7 +196,7 @@ app.on("open-url", (event, url) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function notifyMainWindow(channel: string, data: unknown) {
|
export function notifyMainWindow(channel: string, data: unknown) {
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
mainWindow.webContents.send(channel, data);
|
mainWindow.webContents.send(channel, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@ import { getTeaPath } from "./tea-dir";
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
import log from "./logger";
|
import log from "./logger";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import get from "./v1-client";
|
||||||
|
import { DeviceAuth } from "../../src/libs/types";
|
||||||
|
import { notifyMainWindow } from "../electron";
|
||||||
|
|
||||||
const sessionFilePath = path.join(getTeaPath(), "tea.xyz/gui/tmp.dat");
|
const sessionFilePath = path.join(getTeaPath(), "tea.xyz/gui/tmp.dat");
|
||||||
const sessionFolder = path.join(getTeaPath(), "tea.xyz/gui");
|
const sessionFolder = path.join(getTeaPath(), "tea.xyz/gui");
|
||||||
|
@ -152,3 +155,44 @@ export async function writeSessionData(data: Session, force?: boolean) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pollInterval: NodeJS.Timer | null;
|
||||||
|
let pollLoop = 0;
|
||||||
|
export async function pollAuth() {
|
||||||
|
if (!pollInterval) {
|
||||||
|
log.info("polling auth starts...");
|
||||||
|
const session = await readSessionData();
|
||||||
|
pollInterval = setInterval(async () => {
|
||||||
|
pollLoop++;
|
||||||
|
log.info("poll auth retry:", pollLoop);
|
||||||
|
let clear = false;
|
||||||
|
let success = false;
|
||||||
|
try {
|
||||||
|
const data = await get<DeviceAuth>(`/auth/device/${session.device_id}`);
|
||||||
|
if (data?.status === "SUCCESS") {
|
||||||
|
await writeSessionData({
|
||||||
|
key: data.key,
|
||||||
|
user: data.user
|
||||||
|
});
|
||||||
|
clear = true;
|
||||||
|
success = true;
|
||||||
|
} else if (pollLoop > 20 && pollInterval) {
|
||||||
|
clear = true;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
clear = true;
|
||||||
|
} finally {
|
||||||
|
if (clear) {
|
||||||
|
pollInterval && clearInterval(pollInterval);
|
||||||
|
pollInterval = null;
|
||||||
|
log.info("polling auth ends.");
|
||||||
|
}
|
||||||
|
if (success) {
|
||||||
|
log.info("updating renderer session");
|
||||||
|
notifyMainWindow("session-update", sessionMemory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { ipcMain, app, BrowserWindow } from "electron";
|
import { ipcMain, app, BrowserWindow } from "electron";
|
||||||
import { deletePackageFolder, getInstalledPackages, cacheImage } from "./tea-dir";
|
import { deletePackageFolder, getInstalledPackages, cacheImage } from "./tea-dir";
|
||||||
import { readSessionData, writeSessionData } from "./auth";
|
import { readSessionData, writeSessionData, pollAuth } from "./auth";
|
||||||
import type { Packages, Session } from "../../src/libs/types";
|
import type { Packages, Session } from "../../src/libs/types";
|
||||||
import log from "./logger";
|
import log from "./logger";
|
||||||
import { syncLogsAt } from "./v1-client";
|
import { syncLogsAt } from "./v1-client";
|
||||||
|
@ -205,4 +205,13 @@ export default function initializeHandlers({ notifyMainWindow }: HandlerOptions)
|
||||||
log.error(error);
|
log.error(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("poll-session", async () => {
|
||||||
|
try {
|
||||||
|
log.info("start polling");
|
||||||
|
return pollAuth();
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "tea",
|
"name": "tea",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "tea gui app",
|
"description": "tea gui app",
|
||||||
"author": "tea.xyz",
|
"author": "tea.xyz",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { authStore, navStore } from "$libs/stores";
|
import { authStore } from "$libs/stores";
|
||||||
import { getSession } from "@native";
|
import { getSession } from "@native";
|
||||||
import { baseUrl } from "$libs/v1-client";
|
import { baseUrl } from "$libs/v1-client";
|
||||||
import { shellOpenExternal } from "@native";
|
import { shellOpenExternal, pollDeviceSession } from "@native";
|
||||||
import mouseLeaveDelay from "@tea/ui/lib/mouse-leave-delay";
|
import mouseLeaveDelay from "@tea/ui/lib/mouse-leave-delay";
|
||||||
const { user } = authStore;
|
const { user } = authStore;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
if (session && session.device_id) {
|
if (session && session.device_id) {
|
||||||
shellOpenExternal(`${baseUrl}/auth/user?device_id=${session.device_id}`);
|
shellOpenExternal(`${baseUrl}/auth/user?device_id=${session.device_id}`);
|
||||||
authStore.pollSession();
|
pollDeviceSession();
|
||||||
} else {
|
} else {
|
||||||
throw new Error("possible no internet connection");
|
throw new Error("possible no internet connection");
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Package, Review, AirtablePost, Bottle } from "@tea/ui/types";
|
import type { Package, Review, AirtablePost, Bottle } from "@tea/ui/types";
|
||||||
import {
|
import type { GUIPackage, Session, Packages, AutoUpdateStatus } from "./types";
|
||||||
type GUIPackage,
|
|
||||||
type DeviceAuth,
|
|
||||||
type Session,
|
|
||||||
AuthStatus,
|
|
||||||
type Packages,
|
|
||||||
type AutoUpdateStatus
|
|
||||||
} from "./types";
|
|
||||||
|
|
||||||
import * as mock from "./native-mock";
|
import * as mock from "./native-mock";
|
||||||
import { PackageStates, type InstalledPackage } from "./types";
|
import { PackageStates, type InstalledPackage } from "./types";
|
||||||
|
@ -130,21 +123,6 @@ export async function getAllPosts(tag?: string): Promise<AirtablePost[]> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDeviceAuth(deviceId: string): Promise<DeviceAuth> {
|
|
||||||
let auth: DeviceAuth = {
|
|
||||||
status: AuthStatus.UNKNOWN,
|
|
||||||
key: ""
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
const data = await apiGet<DeviceAuth>(`/auth/device/${deviceId}`);
|
|
||||||
if (data) auth = data;
|
|
||||||
} catch (error) {
|
|
||||||
log.error(error);
|
|
||||||
auth = await getDeviceAuth(deviceId);
|
|
||||||
}
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPackageBottles(packageName: string): Promise<Bottle[]> {
|
export async function getPackageBottles(packageName: string): Promise<Bottle[]> {
|
||||||
try {
|
try {
|
||||||
return withRetry(async () => {
|
return withRetry(async () => {
|
||||||
|
@ -296,3 +274,11 @@ export const getAutoUpdateStatus = async (): Promise<AutoUpdateStatus> => {
|
||||||
return { status: "up-to-date" };
|
return { status: "up-to-date" };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const pollDeviceSession = async () => {
|
||||||
|
try {
|
||||||
|
await ipcRenderer.invoke("poll-session");
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -326,11 +326,6 @@ export async function getAllPosts(type: string): Promise<AirtablePost[]> {
|
||||||
return posts;
|
return posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDeviceAuth(deviceId: string): Promise<any> {
|
|
||||||
const data = await v1Client.get<any>(`/auth/device/${deviceId}`);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPackageBottles(name: string): Promise<Bottle[]> {
|
export async function getPackageBottles(name: string): Promise<Bottle[]> {
|
||||||
return [
|
return [
|
||||||
{ name, platform: "darwin", arch: "aarch64", version: "3.39.4", bytes: 123456 },
|
{ name, platform: "darwin", arch: "aarch64", version: "3.39.4", bytes: 123456 },
|
||||||
|
@ -411,3 +406,7 @@ export const getAutoUpdateStatus = async (): Promise<AutoUpdateStatus> => {
|
||||||
export async function openPackageEntrypointInTerminal(pkg: string) {
|
export async function openPackageEntrypointInTerminal(pkg: string) {
|
||||||
//noop
|
//noop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const pollDeviceSession = async () => {
|
||||||
|
console.log("do nothing");
|
||||||
|
};
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
import { getDeviceAuth } from "@native";
|
import { listenToChannel } from "@native";
|
||||||
import type { Developer } from "@tea/ui/types";
|
import type { Developer } from "@tea/ui/types";
|
||||||
import type { Session } from "$libs/types";
|
import type { Session } from "$libs/types";
|
||||||
import { getSession as electronGetSession, updateSession as electronUpdateSession } from "@native";
|
import { getSession as electronGetSession, updateSession as electronUpdateSession } from "@native";
|
||||||
import { initSentry } from "../sentry";
|
import { initSentry } from "../sentry";
|
||||||
|
import log from "$libs/logger";
|
||||||
|
|
||||||
export let session: Session | null = null;
|
export let session: Session | null = null;
|
||||||
export const getSession = async (): Promise<Session | null> => {
|
export const getSession = async (): Promise<Session | null> => {
|
||||||
|
@ -15,7 +16,6 @@ export const getSession = async (): Promise<Session | null> => {
|
||||||
export default function initAuthStore() {
|
export default function initAuthStore() {
|
||||||
const user = writable<Developer | undefined>();
|
const user = writable<Developer | undefined>();
|
||||||
const sessionStore = writable<Session>({});
|
const sessionStore = writable<Session>({});
|
||||||
let pollLoop = 0;
|
|
||||||
|
|
||||||
const deviceIdStore = writable<string>("");
|
const deviceIdStore = writable<string>("");
|
||||||
let deviceId = "";
|
let deviceId = "";
|
||||||
|
@ -31,7 +31,16 @@ export default function initAuthStore() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let timer: NodeJS.Timer | null;
|
listenToChannel("session-update", (data: Session) => {
|
||||||
|
log.info("session update renderer", data);
|
||||||
|
sessionStore.update((val) => ({
|
||||||
|
...val,
|
||||||
|
...data
|
||||||
|
}));
|
||||||
|
if (data.user) {
|
||||||
|
user.set(data.user);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
async function updateSession(data: Session) {
|
async function updateSession(data: Session) {
|
||||||
sessionStore.update((val) => ({
|
sessionStore.update((val) => ({
|
||||||
|
@ -43,34 +52,6 @@ export default function initAuthStore() {
|
||||||
await electronUpdateSession(data);
|
await electronUpdateSession(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function pollSession() {
|
|
||||||
if (!timer) {
|
|
||||||
timer = setInterval(async () => {
|
|
||||||
pollLoop++;
|
|
||||||
try {
|
|
||||||
const data = await getDeviceAuth(deviceId);
|
|
||||||
if (data.status === "SUCCESS") {
|
|
||||||
updateSession({
|
|
||||||
key: data.key,
|
|
||||||
user: data.user
|
|
||||||
});
|
|
||||||
user.set(data.user!);
|
|
||||||
timer && clearInterval(timer);
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pollLoop > 20 && timer) {
|
|
||||||
clearInterval(timer);
|
|
||||||
pollLoop = 0;
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearSession() {
|
function clearSession() {
|
||||||
updateSession({ key: undefined, user: undefined });
|
updateSession({ key: undefined, user: undefined });
|
||||||
user.set(undefined);
|
user.set(undefined);
|
||||||
|
@ -81,7 +62,6 @@ export default function initAuthStore() {
|
||||||
session: sessionStore,
|
session: sessionStore,
|
||||||
deviceId,
|
deviceId,
|
||||||
deviceIdStore,
|
deviceIdStore,
|
||||||
pollSession,
|
|
||||||
clearSession,
|
clearSession,
|
||||||
updateSession
|
updateSession
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue