From 70452ec84141f50ea46ac5a41ce0397c22b79998 Mon Sep 17 00:00:00 2001 From: Arnab Chakraborty <11457760+Rocky43007@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:00:59 +0300 Subject: [PATCH] wip: Getting User Data from backend --- core/src/api/keys.rs | 56 ++++++++++++++++++- .../settings/client/account/Login.tsx | 7 ++- .../client/account/handlers/cookieHandler.ts | 56 +++++-------------- .../settings/client/account/index.tsx | 23 +++++++- packages/client/src/core.ts | 1 + 5 files changed, 94 insertions(+), 49 deletions(-) diff --git a/core/src/api/keys.rs b/core/src/api/keys.rs index 6fa72cfbb..4d63d4f2d 100644 --- a/core/src/api/keys.rs +++ b/core/src/api/keys.rs @@ -3,6 +3,7 @@ use keyring::Entry; use rspc::alpha::AlphaRouter; +use serde_json::Value; use tracing::{debug, error}; // use sd_crypto::keys::keymanager::{StoredKey, StoredKeyType}; // use sd_crypto::primitives::SECRET_KEY_IDENTIFIER; @@ -73,7 +74,7 @@ pub(crate) fn mount() -> AlphaRouter { }; match entry.set_password(key.as_str()) { - Ok(_) => debug!("Key set successfully"), + Ok(_) => (), Err(e) => { error!("Error setting key: {}", e); return Err(rspc::Error::new( @@ -114,13 +115,64 @@ pub(crate) fn mount() -> AlphaRouter { }; debug!( - "Key retrieved successfully: service={service}", + "Key retrieved successfully: service={service}, data={_data}", + _data = data, service = "spacedrive-auth-service", ); Ok(data) }) }) + .procedure("getAccessToken", { + R.query(|_, _: ()| async move { + let username = whoami::username(); + let entry = match Entry::new("spacedrive-auth-service", username.as_str()) { + Ok(entry) => entry, + Err(e) => { + error!("Error creating entry: {}", e); + return Err(rspc::Error::new( + rspc::ErrorCode::InternalServerError, + "Error creating entry".to_string(), + )); + } + }; + + let data = match entry.get_password() { + Ok(key) => key, + Err(e) => { + error!("Error retrieving key: {}. Does the key exist yet?", e); + return Ok("".to_string()); + } + }; + + let json_value: Value = match serde_json::from_str(&data) { + Ok(json_value) => json_value, + Err(e) => { + error!("Error parsing JSON value: {}", e); + return Ok("".to_string()); + } + }; + let cookie_str = match json_value[0].as_str() { + Some(cookie_str) => cookie_str, + None => { + error!("Error parsing JSON value: {}", "No cookie string found"); + return Ok("".to_string()); + } + }; + + // Extract the sFrontToken value + let token_start = "st-access-token="; + let token_end = ";"; + let token = cookie_str[token_start.len()..cookie_str.find(token_end).expect("Failed to find token end")].to_string(); + + debug!( + "Key retrieved successfully: service={service}", + service = "spacedrive-auth-service", + ); + + Ok(token) + }) + }) } //NOTE(@Rocky43007): OLD PROCEDURES -> MAY BE USEFUL FOR REFERENCE AND COULD BE USED IN THE FUTURE diff --git a/interface/app/$libraryId/settings/client/account/Login.tsx b/interface/app/$libraryId/settings/client/account/Login.tsx index 8354c6d37..dce7c310c 100644 --- a/interface/app/$libraryId/settings/client/account/Login.tsx +++ b/interface/app/$libraryId/settings/client/account/Login.tsx @@ -1,8 +1,8 @@ -import { useZodForm } from '@sd/client'; -import { Button, Form, Input, toast, z } from '@sd/ui'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { Controller } from 'react-hook-form'; import { signIn } from 'supertokens-web-js/recipe/emailpassword'; +import { nonLibraryClient, useZodForm } from '@sd/client'; +import { Button, Form, Input, toast, z } from '@sd/ui'; import ShowPassword from './ShowPassword'; async function signInClicked(email: string, password: string) { @@ -63,6 +63,7 @@ const Login = () => { password: '' } }); + return (
{ diff --git a/interface/app/$libraryId/settings/client/account/handlers/cookieHandler.ts b/interface/app/$libraryId/settings/client/account/handlers/cookieHandler.ts index e549730ca..f4ac8cb15 100644 --- a/interface/app/$libraryId/settings/client/account/handlers/cookieHandler.ts +++ b/interface/app/$libraryId/settings/client/account/handlers/cookieHandler.ts @@ -1,20 +1,10 @@ import { CookieHandlerInterface } from "supertokens-website/utils/cookieHandler/types"; import { nonLibraryClient } from '@sd/client' -function getCookiesFromStorage(): string { - let cookiesFromStorage: string = ""; +async function getCookiesFromStorage(): Promise { + const cookiesFromStorage = await nonLibraryClient.query(['keys.get']) - nonLibraryClient.query(['keys.get']).then((response) => { - // Debugging - console.log("rspc response: ", response); - const cookiesArrayFromStorage: string[] = JSON.parse(response); - console.log("Cookies fetched from storage: ", cookiesArrayFromStorage); - - // Actual - cookiesFromStorage = response; - }).catch((e) => { - console.error("Error fetching cookies from storage: ", e); - }); + console.log("Cookies from storage (getCookie): ", cookiesFromStorage); if (cookiesFromStorage.length === 0) { return ""; @@ -61,31 +51,18 @@ function getCookiesFromStorage(): string { * After processing and removing expired cookies we need to update the cookies * in storage so we dont have to process the expired ones again */ - // window.localStorage.setItem(frontendCookiesKey, JSON.stringify(cookieArrayToReturn)); - nonLibraryClient.mutation(['keys.set', JSON.stringify(cookieArrayToReturn)]).then(() => { - console.log("Cookies set successfully"); - }).catch((e) => { - console.error("Error setting cookies to storage: ", e); - return; - }) + await nonLibraryClient.mutation(['keys.set', JSON.stringify(cookieArrayToReturn)]) return cookieArrayToReturn.join("; "); } -function setCookieToStorage(cookieString: string) { +async function setCookieToStorage(cookieString: string): Promise { const cookieName = cookieString.split(";")[0]?.split("=")[0]; + console.log("Setting cookie: ", cookieName); - let cookiesFromStorage: string = ""; - nonLibraryClient.query(['keys.get']).then((response) => { - // Debugging - const cookiesArrayFromStorage: string[] = JSON.parse(response); - console.log("Cookies fetched from storage: ", cookiesArrayFromStorage); + const cookiesFromStorage = await nonLibraryClient.query(['keys.get']) - // Actual - cookiesFromStorage = response; - }).catch((e) => { - console.error("Error fetching cookies from storage: ", e); - }); + console.log("Cookies from storage: ", cookiesFromStorage); let cookiesArray: string[] = []; @@ -93,6 +70,7 @@ function setCookieToStorage(cookieString: string) { const cookiesArrayFromStorage: string[] = JSON.parse(cookiesFromStorage); cookiesArray = cookiesArrayFromStorage; } + console.log("Cookies array: ", cookiesArray); let cookieIndex = -1; @@ -104,6 +82,7 @@ function setCookieToStorage(cookieString: string) { break; } } + console.log("Cookie index: ", cookieIndex); /** * If a cookie with the same name already exists (index != -1) then we @@ -116,26 +95,19 @@ function setCookieToStorage(cookieString: string) { } else { cookiesArray.push(cookieString); } + console.log("Updated cookies array: ", cookiesArray); - nonLibraryClient.mutation(['keys.set', JSON.stringify(cookiesArray)]).then(() => { - console.log("Cookies set successfully"); - }).catch((e) => { - console.error("Error setting cookies to storage: ", e); - return; - }) - - console.log("Setting cookies to storage: ", cookiesArray); + await nonLibraryClient.mutation(['keys.set', JSON.stringify(cookiesArray)]) } export default function getCookieHandler(original: CookieHandlerInterface): CookieHandlerInterface { return { ...original, getCookie: async function () { - const cookies = getCookiesFromStorage(); - return cookies; + return getCookiesFromStorage(); }, setCookie: async function (cookieString: string) { - setCookieToStorage(cookieString); + return setCookieToStorage(cookieString); }, }; } diff --git a/interface/app/$libraryId/settings/client/account/index.tsx b/interface/app/$libraryId/settings/client/account/index.tsx index adc6c2762..751a1c349 100644 --- a/interface/app/$libraryId/settings/client/account/index.tsx +++ b/interface/app/$libraryId/settings/client/account/index.tsx @@ -1,6 +1,7 @@ +import { useEffect, useState } from 'react'; +import Session from 'supertokens-web-js/recipe/session'; import { auth, useBridgeMutation, useBridgeQuery, useFeatureFlag } from '@sd/client'; import { Button, Input, toast } from '@sd/ui'; -import { useEffect, useState } from 'react'; import { useLocale } from '~/hooks'; import { Heading } from '../../Layout'; @@ -10,7 +11,25 @@ import Tabs from './Tabs'; export const Component = () => { const { t } = useLocale(); const me = useBridgeQuery(['auth.me'], { retry: false }); + const token = useBridgeQuery(['keys.getAccessToken'], { retry: false }); const authStore = auth.useStateSnapshot(); + useEffect(() => { + async function _() { + console.log("Token data: ", token.data); + const user_data = await fetch('http://localhost:9000/api/user', { + method: 'GET', + headers: { + 'Authorization': `Bearer ${token.data ?? ''}` + } + }); + const data = await user_data.json(); + return data; + } + _().then((data) => { + console.log("User data: ", data); + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); return ( <> { />
{authStore.status === 'notLoggedIn' ? ( - + ) : ( )} diff --git a/packages/client/src/core.ts b/packages/client/src/core.ts index bfb244a16..e51821732 100644 --- a/packages/client/src/core.ts +++ b/packages/client/src/core.ts @@ -19,6 +19,7 @@ export type Procedures = { { key: "jobs.isActive", input: LibraryArgs, result: boolean } | { key: "jobs.reports", input: LibraryArgs, result: JobGroup[] } | { key: "keys.get", input: never, result: string } | + { key: "keys.getAccessToken", input: never, result: string } | { key: "labels.count", input: LibraryArgs, result: number } | { key: "labels.get", input: LibraryArgs, result: Label | null } | { key: "labels.getForObject", input: LibraryArgs, result: Label[] } |