From 7264c6ed32df98647c24c1cb68cc9e4a05fdd757 Mon Sep 17 00:00:00 2001 From: John Costa Date: Fri, 11 Apr 2025 19:58:25 +0100 Subject: [PATCH] feat(authorization): e2e working authorization --- frontend/bun.lockb | Bin 118146 -> 118512 bytes frontend/package.json | 1 + frontend/src-tauri/src/lib.rs | 3 +-- frontend/src/Login.tsx | 28 +++++++++++++++++----------- frontend/src/ProtectedRoute.tsx | 30 ++++++++++++++++++++++++++++++ frontend/src/index.tsx | 8 ++++++-- frontend/src/network/index.ts | 18 +++++++++++++++--- 7 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 frontend/src/ProtectedRoute.tsx diff --git a/frontend/bun.lockb b/frontend/bun.lockb index 63e774e75f82d0205813de2bdbb20b73eeb175e0..3e7fff770f996de721d726592f7206885747c900 100755 GIT binary patch delta 18514 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 delta 18391 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 YVoRrCtRmaeYdGuPU`y$2<{bZj0Evfj#Q*>R diff --git a/frontend/package.json b/frontend/package.json index 1060b4c..05119e0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,6 +23,7 @@ "@tauri-apps/plugin-opener": "^2", "clsx": "^2.1.1", "fuse.js": "^7.1.0", + "jwt-decode": "^4.0.0", "solid-js": "^1.9.3", "solid-motionone": "^1.0.3", "tailwind-scrollbar-hide": "^2.0.0", diff --git a/frontend/src-tauri/src/lib.rs b/frontend/src-tauri/src/lib.rs index 63395df..7a0decf 100644 --- a/frontend/src-tauri/src/lib.rs +++ b/frontend/src-tauri/src/lib.rs @@ -7,7 +7,6 @@ use std::sync::Arc; use std::sync::Mutex; use tauri::AppHandle; use tauri::Emitter; -use tauri::TitleBarStyle; use tauri::{WebviewUrl, WebviewWindowBuilder}; struct WatcherState { @@ -116,7 +115,7 @@ pub fn run() { .setup(|app| { let win_builder = WebviewWindowBuilder::new(app, "main", WebviewUrl::default()) .inner_size(480.0, 360.0) - .hidden_title(true) + // .hidden_title(true) .resizable(true); // set transparent title bar only when building for macOS #[cfg(target_os = "macos")] diff --git a/frontend/src/Login.tsx b/frontend/src/Login.tsx index 377276e..344d8cd 100644 --- a/frontend/src/Login.tsx +++ b/frontend/src/Login.tsx @@ -2,6 +2,8 @@ import { Button } from "@kobalte/core/button"; import { TextField } from "@kobalte/core/text-field"; import { createSignal, Show, type Component } from "solid-js"; import { postCode, postLogin } from "./network"; +import { isTokenValid } from "./ProtectedRoute"; +import { Navigate } from "@solidjs/router"; export const Login: Component = () => { let form: HTMLFormElement | undefined; @@ -35,19 +37,23 @@ export const Login: Component = () => { } }; + const isAuthorized = isTokenValid(); + return ( -
- - Email - - - - - Code + }> + + + Email - - - + + + Code + + + + + +
); }; diff --git a/frontend/src/ProtectedRoute.tsx b/frontend/src/ProtectedRoute.tsx new file mode 100644 index 0000000..e4bc3c9 --- /dev/null +++ b/frontend/src/ProtectedRoute.tsx @@ -0,0 +1,30 @@ +import { type Component, type JSX, Show } from "solid-js"; +import { jwtDecode } from "jwt-decode"; +import { Navigate } from "@solidjs/router"; + +export const isTokenValid = (): boolean => { + const token = localStorage.getItem("access"); + + if (token == null) { + return false; + } + + try { + jwtDecode(token); + return true; + } catch (err) { + return false; + } +}; + +export const ProtectedRoute: Component<{ children?: JSX.Element }> = ( + props, +) => { + const isValid = isTokenValid(); + + return ( + }> + {props.children} + + ); +}; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 61dd91b..fb4943b 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -5,13 +5,17 @@ import "./index.css"; import { Route, Router } from "@solidjs/router"; import { ImagePage } from "./ImagePage"; import { Login } from "./Login"; +import { ProtectedRoute } from "./ProtectedRoute"; render( () => ( - - + + + + + ), document.getElementById("root") as HTMLElement, diff --git a/frontend/src/network/index.ts b/frontend/src/network/index.ts index 7e4084b..9c5100c 100644 --- a/frontend/src/network/index.ts +++ b/frontend/src/network/index.ts @@ -19,12 +19,24 @@ type BaseRequestParams = Partial<{ const getBaseRequest = ({ path, body, method }: BaseRequestParams): Request => { return new Request(`http://localhost:3040/${path}`, { - headers: { userId: "1db09f34-b155-4bf2-b606-dda25365fc89" }, body, method, }); }; +const getBaseAuthorizedRequest = ({ + path, + body, + method, +}: BaseRequestParams): Request => { + return new Request(`http://localhost:3040/${path}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("access")?.toString()}`, + }, + body, + method, + }); +}; const sendImageResponseValidator = strictObject({ ID: pipe(string(), uuid()), ImageID: pipe(string(), uuid()), @@ -35,7 +47,7 @@ export const sendImage = async ( imageName: string, base64Image: string, ): Promise> => { - const request = getBaseRequest({ + const request = getBaseAuthorizedRequest({ path: `image/${imageName}`, body: base64Image, method: "POST", @@ -107,7 +119,7 @@ const getUserImagesResponseValidator = array(dataTypeValidator); export type UserImage = InferOutput; export const getUserImages = async (): Promise => { - const request = getBaseRequest({ path: "image" }); + const request = getBaseAuthorizedRequest({ path: "image" }); const res = await fetch(request).then((res) => res.json());