diff --git a/frontend/bun.lockb b/frontend/bun.lockb
index 63e774e..3e7fff7 100755
Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ
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 (
-
+
+
+ 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());