From 742f5064c1cd596f983b0239f0ee41ba7f5f72c0 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 5 Jan 2023 14:26:16 +0800 Subject: [PATCH] #78 store session data locally: ~/.tea/tea.xyz/gui/tmp.dat --- .../components/NavBar/ProfileNavButton.svelte | 4 +- modules/gui/src/libs/api/mock.ts | 7 +- modules/gui/src/libs/api/tauri.ts | 9 +- modules/gui/src/libs/stores/auth.ts | 90 +++++++++++++------ 4 files changed, 76 insertions(+), 34 deletions(-) diff --git a/modules/gui/src/components/NavBar/ProfileNavButton.svelte b/modules/gui/src/components/NavBar/ProfileNavButton.svelte index 54d4f0b..d7b53ed 100644 --- a/modules/gui/src/components/NavBar/ProfileNavButton.svelte +++ b/modules/gui/src/components/NavBar/ProfileNavButton.svelte @@ -4,10 +4,10 @@ import type { User } from '@tea/ui/types'; let user: User | null = null; - const authPage = `http://localhost:3000/v1/auth/user?device_id=${authStore.deviceId}`; // https://api.tea.xyz/v1/auth/user?device_id=device_id + const deviceId = authStore.deviceIdStore; const openGithub = () => { - open(authPage); + open(`http://localhost:3000/v1/auth/user?device_id=${$deviceId}`); try { authStore.pollSession(); } catch (error) { diff --git a/modules/gui/src/libs/api/mock.ts b/modules/gui/src/libs/api/mock.ts index dd5b2c0..bca61a8 100644 --- a/modules/gui/src/libs/api/mock.ts +++ b/modules/gui/src/libs/api/mock.ts @@ -323,8 +323,7 @@ export async function getCategorizedPackages(): Promise { ]; } -export async function getDeviceAuth(): Promise { - const deviceId = 'xyz123'; +export async function getDeviceAuth(deviceId: string): Promise { // const data = await get(`/auth/device/${deviceId}`); return { status: 'SUCCESS', @@ -354,3 +353,7 @@ export async function getPackageBottles(name: string): Promise { { name, platform: 'linux', arch: 'x86-64', version: '3.40.0' } ]; } + +export async function registerDevice(): Promise { + return 'uuid1234'; +} diff --git a/modules/gui/src/libs/api/tauri.ts b/modules/gui/src/libs/api/tauri.ts index 9b0500b..e9d99d5 100644 --- a/modules/gui/src/libs/api/tauri.ts +++ b/modules/gui/src/libs/api/tauri.ts @@ -175,9 +175,9 @@ type DeviceAuth = { key: string; }; -export async function getDeviceAuth(): Promise { - const deviceId = 'xyxz123'; +export async function getDeviceAuth(deviceId: string): Promise { const data = await get(`/auth/device/${deviceId}`); + return data; } export async function getPackageBottles(packageName: string): Promise { @@ -188,3 +188,8 @@ export async function getPackageBottles(packageName: string): Promise console.log('got bottles', data); return data; } + +export async function registerDevice(): Promise { + const { deviceId } = await get<{ deviceId: string }>('/auth/registerDevice'); + return deviceId; +} diff --git a/modules/gui/src/libs/stores/auth.ts b/modules/gui/src/libs/stores/auth.ts index 3ccf368..bcbfe21 100644 --- a/modules/gui/src/libs/stores/auth.ts +++ b/modules/gui/src/libs/stores/auth.ts @@ -1,42 +1,58 @@ import { writable } from 'svelte/store'; import { BaseDirectory, createDir, readTextFile, writeTextFile } from '@tauri-apps/api/fs'; import { join } from '@tauri-apps/api/path'; -import { getDeviceAuth } from '@api'; +import { getDeviceAuth, registerDevice } from '@api'; import type { User } from '@tea/ui/types'; const basePath = '.tea/tea.xyz/gui'; interface Session { - key: string; - user: any; + device_id?: string; + key?: string; + user?: any; } export default function initAuthStore() { - const deviceId = 'abcdevf'; // ideally randomly generated on install - const session = writable(); + const session = writable({}); let pollLoop = 0; - initSession(); + + const deviceIdStore = writable(''); + let deviceId = ''; + + initSession().then((sess) => { + if (sess) { + session.set(sess); + deviceIdStore.set(sess.device_id!); + deviceId = sess.device_id!; + } + }); let timer: NodeJS.Timer | null; - // TODO: - // fetch session data from local - // fetch session data remotely - // update local session data + + async function updateSession(data: Session) { + const localSession = { + device_id: deviceId, + key: data.key, + user: data.user + }; + saveLocallySessionData(localSession); + session.set(localSession); + } async function pollSession() { if (!timer) { timer = setInterval(async () => { pollLoop++; try { - const data = await getDeviceAuth(); + const data = await getDeviceAuth(deviceId); + console.log('dd', deviceId, data); if (data.status === 'SUCCESS') { - session.set({ + updateSession({ key: data.key, user: data.user }); timer && clearInterval(timer); timer = null; } - console.log(data); } catch (error) { console.error(error); } @@ -52,6 +68,7 @@ export default function initAuthStore() { return { deviceId, + deviceIdStore, subscribe: (cb: (u: User) => void) => { return session.subscribe((v) => v && cb(v.user)); }, @@ -60,36 +77,53 @@ export default function initAuthStore() { } const initSession = async (): Promise => { - await createGuiDataFolder(); - const session = await getSessionData(); - console.log(session); -}; - -const createGuiDataFolder = async () => { await createDir(basePath, { dir: BaseDirectory.Home, recursive: true }); + const session = await getLocalSessionData(); + return session; }; -const getSessionData = async (): Promise => { +const getLocalSessionData = async (): Promise => { const sessionFilePath = await join(basePath, 'tmp.dat'); + let data: Session; try { - const data = await readTextFile(sessionFilePath, { + const encryptedData = await readTextFile(sessionFilePath, { dir: BaseDirectory.Home }); // TODO: decrypt then return - console.log('data:', data); + data = JSON.parse(encryptedData || '{}'); } catch (error) { console.error(error); - await writeTextFile(sessionFilePath, '', { - dir: BaseDirectory.Home - }); + const deviceId = await getDeviceId(); + data = { + device_id: deviceId + }; + await saveLocallySessionData(data); } - console.log(sessionFilePath); + + return data; }; -const saveSessionData = async (data: { [key: string]: string | number | Date }) => { +const saveLocallySessionData = async (data: Session) => { const sessionFilePath = await join(basePath, 'tmp.dat'); - // TODO: encrypt and write + // TODO: encrypt first + await writeTextFile(sessionFilePath, JSON.stringify(data), { + dir: BaseDirectory.Home + }); +}; + +const getDeviceId = async (): Promise => { + const hasLocal = false; + // get from local data + // else get from server + // GET /v1/auth/registerDevice + let deviceId = ''; + if (hasLocal) { + } else { + deviceId = await registerDevice(); + } + console.log('deviceId:', deviceId); + return deviceId; };